From 9ddd3335aedf25405d0a27a93afad90cfc838c50 Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Mon, 16 Dec 2024 16:23:53 +0900 Subject: [PATCH 01/12] Rename getter --- accounts/abi/bind/backends/blockchain_test.go | 2 +- blockchain/tx_pool.go | 6 +-- blockchain/tx_pool_test.go | 2 +- blockchain/types/derivesha/derive_sha_test.go | 2 +- blockchain/types/derivesha/mux.go | 4 +- consensus/istanbul/backend/engine.go | 6 +-- consensus/istanbul/backend/engine_test.go | 18 ++++---- consensus/istanbul/backend/snapshot.go | 4 +- kaiax/gov/README.md | 14 +++---- kaiax/gov/contractgov/README.md | 11 ++--- kaiax/gov/contractgov/impl/api.go | 2 +- kaiax/gov/contractgov/impl/error.go | 2 +- kaiax/gov/contractgov/impl/getter.go | 8 ++-- kaiax/gov/contractgov/impl/getter_test.go | 8 ++-- kaiax/gov/contractgov/interface.go | 4 +- .../gov/contractgov/mock/contractgov_mock.go | 24 +++++------ kaiax/gov/headergov/README.md | 15 +++---- kaiax/gov/headergov/impl/api.go | 2 +- kaiax/gov/headergov/impl/consensus.go | 4 +- kaiax/gov/headergov/impl/consensus_test.go | 2 +- kaiax/gov/headergov/impl/getter.go | 4 +- kaiax/gov/headergov/impl/getter_test.go | 4 +- kaiax/gov/headergov/interface.go | 4 +- kaiax/gov/headergov/mock/headergov_mock.go | 42 +++++++++---------- kaiax/gov/impl/api.go | 2 +- kaiax/gov/impl/getter.go | 6 +-- kaiax/gov/impl/getter_test.go | 38 ++++++++--------- kaiax/gov/interface.go | 2 +- kaiax/gov/mock/govmodule_mock.go | 28 ++++++------- kaiax/reward/config.go | 4 +- kaiax/reward/impl/init_test.go | 2 +- kaiax/supply/impl/testutil_test.go | 2 +- node/cn/api_backend.go | 4 +- node/cn/api_backend_test.go | 6 +-- node/cn/backend.go | 2 +- node/cn/gasprice/feehistory.go | 2 +- node/cn/gasprice/feehistory_test.go | 4 +- node/cn/gasprice/gasprice.go | 2 +- node/cn/gasprice/gasprice_test.go | 6 +-- node/sc/mainbridge_test.go | 2 +- tests/gov_contract_test.go | 8 ++-- tests/gov_test.go | 2 +- work/worker.go | 2 +- 43 files changed, 160 insertions(+), 158 deletions(-) diff --git a/accounts/abi/bind/backends/blockchain_test.go b/accounts/abi/bind/backends/blockchain_test.go index c0083d86d..8db5fe905 100644 --- a/accounts/abi/bind/backends/blockchain_test.go +++ b/accounts/abi/bind/backends/blockchain_test.go @@ -63,7 +63,7 @@ type dummyGovModule struct { chainConfig *params.ChainConfig } -func (d *dummyGovModule) EffectiveParamSet(blockNum uint64) gov.ParamSet { +func (d *dummyGovModule) GetParamSet(blockNum uint64) gov.ParamSet { return gov.ParamSet{UnitPrice: d.chainConfig.UnitPrice} } diff --git a/blockchain/tx_pool.go b/blockchain/tx_pool.go index 2e37d3daa..2778d66ff 100644 --- a/blockchain/tx_pool.go +++ b/blockchain/tx_pool.go @@ -179,7 +179,7 @@ func (config *TxPoolConfig) sanitize() TxPoolConfig { } type GovModule interface { - EffectiveParamSet(blockNum uint64) gov.ParamSet + GetParamSet(blockNum uint64) gov.ParamSet } // TxPool contains all currently known transactions. Transactions @@ -233,7 +233,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block // Sanitize the input to ensure no vulnerable gas prices are set config = (&config).sanitize() - pset := govModule.EffectiveParamSet(chain.CurrentBlock().NumberU64() + 1) + pset := govModule.GetParamSet(chain.CurrentBlock().NumberU64() + 1) // Create the transaction pool with its initial settings pool := &TxPool{ @@ -502,7 +502,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { // It needs to update gas price of tx pool since magma hardfork if pool.rules.IsMagma { - pset := pool.govModule.EffectiveParamSet(newHead.Number.Uint64() + 1) + pset := pool.govModule.GetParamSet(newHead.Number.Uint64() + 1) pool.gasPrice = misc.NextMagmaBlockBaseFee(newHead, pset.ToKip71Config()) } } diff --git a/blockchain/tx_pool_test.go b/blockchain/tx_pool_test.go index 2fca3eddf..0cb19cafb 100644 --- a/blockchain/tx_pool_test.go +++ b/blockchain/tx_pool_test.go @@ -63,7 +63,7 @@ type dummyGovModule struct { chainConfig *params.ChainConfig } -func (m *dummyGovModule) EffectiveParamSet(blockNum uint64) gov.ParamSet { +func (m *dummyGovModule) GetParamSet(blockNum uint64) gov.ParamSet { return gov.ParamSet{UnitPrice: m.chainConfig.UnitPrice} } diff --git a/blockchain/types/derivesha/derive_sha_test.go b/blockchain/types/derivesha/derive_sha_test.go index 82830916e..ffb3ffc3b 100644 --- a/blockchain/types/derivesha/derive_sha_test.go +++ b/blockchain/types/derivesha/derive_sha_test.go @@ -49,7 +49,7 @@ var testGovSchedule = map[uint64]int{ 8: types.ImplDeriveShaConcat, } -func (e *testGov) EffectiveParamSet(num uint64) gov.ParamSet { +func (e *testGov) GetParamSet(num uint64) gov.ParamSet { return gov.ParamSet{ DeriveShaImpl: uint64(testGovSchedule[num]), } diff --git a/blockchain/types/derivesha/mux.go b/blockchain/types/derivesha/mux.go index d4f3ea7e4..224110dd7 100644 --- a/blockchain/types/derivesha/mux.go +++ b/blockchain/types/derivesha/mux.go @@ -37,7 +37,7 @@ type IDeriveSha interface { } type GovModule interface { - EffectiveParamSet(num uint64) gov.ParamSet + GetParamSet(num uint64) gov.ParamSet } var ( @@ -85,7 +85,7 @@ func getType(num *big.Int) int { // and unit tests. govModule != nil if blockchain.InitDeriveShaWithGov is used, // in ordinary blockchain processing. if govModule != nil { - pset := govModule.EffectiveParamSet(num.Uint64()) + pset := govModule.GetParamSet(num.Uint64()) implType = int(pset.DeriveShaImpl) } diff --git a/consensus/istanbul/backend/engine.go b/consensus/istanbul/backend/engine.go index 13a35261b..f80816cba 100644 --- a/consensus/istanbul/backend/engine.go +++ b/consensus/istanbul/backend/engine.go @@ -212,7 +212,7 @@ func (sb *backend) verifyHeader(chain consensus.ChainReader, header *types.Heade if chain.Config().IsMagmaForkEnabled(header.Number) { // the kip71Config used when creating the block number is a previous block config. blockNum := header.Number.Uint64() - pset := sb.govModule.EffectiveParamSet(blockNum) + pset := sb.govModule.GetParamSet(blockNum) kip71 := pset.ToKip71Config() if err := misc.VerifyMagmaHeader(parents[len(parents)-1], header, kip71); err != nil { return err @@ -427,7 +427,7 @@ func (sb *backend) Prepare(chain consensus.ChainReader, header *types.Header) er header.BlockScore = defaultBlockScore // If it reaches the Epoch, governance config will be added to block header - pset := sb.govModule.EffectiveParamSet(number) + pset := sb.govModule.GetParamSet(number) if number%pset.Epoch == 0 { if g := sb.governance.GetGovernanceChange(); g != nil { if data, err := json.Marshal(g); err != nil { @@ -778,7 +778,7 @@ func (sb *backend) initSnapshot(chain consensus.ChainReader) (*Snapshot, error) return nil, err } - pset := sb.govModule.EffectiveParamSet(0) + pset := sb.govModule.GetParamSet(0) valSet := validator.NewValidatorSet(istanbulExtra.Validators, nil, istanbul.ProposerPolicy(pset.ProposerPolicy), pset.CommitteeSize, chain) diff --git a/consensus/istanbul/backend/engine_test.go b/consensus/istanbul/backend/engine_test.go index 834b33c9e..e6efe2ddf 100644 --- a/consensus/istanbul/backend/engine_test.go +++ b/consensus/istanbul/backend/engine_test.go @@ -794,8 +794,8 @@ func TestRewardDistribution(t *testing.T) { chain.RegisterExecutionModule(engine.govModule) defer engine.Stop() - assert.Equal(t, uint64(testEpoch), engine.govModule.EffectiveParamSet(0).Epoch) - assert.Equal(t, mintAmount, engine.govModule.EffectiveParamSet(0).MintingAmount.Uint64()) + assert.Equal(t, uint64(testEpoch), engine.govModule.GetParamSet(0).Epoch) + assert.Equal(t, mintAmount, engine.govModule.GetParamSet(0).MintingAmount.Uint64()) var previousBlock, currentBlock *types.Block = nil, chain.Genesis() @@ -1744,7 +1744,7 @@ func TestGovernance_Votes(t *testing.T) { chain.RegisterExecutionModule(engine.valsetModule, engine.govModule) // test initial governance items - pset := engine.govModule.EffectiveParamSet(chain.CurrentHeader().Number.Uint64() + 1) + pset := engine.govModule.GetParamSet(chain.CurrentHeader().Number.Uint64() + 1) assert.Equal(t, uint64(3), pset.Epoch) assert.Equal(t, "single", pset.GovernanceMode) assert.Equal(t, uint64(21), pset.CommitteeSize) @@ -1787,7 +1787,7 @@ func TestGovernance_Votes(t *testing.T) { if blockNumber == 0 { blockNumber = chain.CurrentBlock().NumberU64() } - partialParamSet := engine.govModule.(*gov_impl.GovModule).Hgm.EffectiveParamsPartial(blockNumber + 1) + partialParamSet := engine.govModule.(*gov_impl.GovModule).Hgm.GetPartialParamSet(blockNumber + 1) switch val := partialParamSet[gov.ParamName(item.key)]; v := val.(type) { case *big.Int: require.Equal(t, item.value, v.String()) @@ -1802,7 +1802,7 @@ func TestGovernance_Votes(t *testing.T) { } func TestGovernance_GovModule(t *testing.T) { - // Test that ReaderEngine (CurrentParams(), EffectiveParamSet(), UpdateParams()) works. + // Test that ReaderEngine (CurrentParams(), GetParamSet(), UpdateParams()) works. type vote struct { name string value interface{} @@ -1856,7 +1856,7 @@ func TestGovernance_GovModule(t *testing.T) { for num := 0; num <= tc.length; num++ { // Validate current params with CurrentParams() and CurrentSetCopy(). // Check that both returns the expected result. - pset := engine.govModule.EffectiveParamSet(uint64(num + 1)) + pset := engine.govModule.GetParamSet(uint64(num + 1)) assertMapSubset(t, tc.expected[num+1], pset.ToGovParamSet().StrMap()) // Place a vote if a vote is scheduled in upcoming block @@ -1874,14 +1874,14 @@ func TestGovernance_GovModule(t *testing.T) { assert.NoError(t, err) } - // Validate historic parameters with EffectiveParamSet() and EffectiveParamsPartial(). + // Validate historic parameters with GetParamSet() and GetPartialParamSet(). // Check that both returns the expected result. for num := 0; num <= tc.length; num++ { - pset := engine.govModule.EffectiveParamSet(uint64(num)) + pset := engine.govModule.GetParamSet(uint64(num)) assertMapSubset(t, tc.expected[num], pset.ToGovParamSet().StrMap()) partialParamSet := make(map[string]any) - for k, v := range engine.govModule.(*gov_impl.GovModule).Hgm.EffectiveParamsPartial(uint64(num + 1)) { + for k, v := range engine.govModule.(*gov_impl.GovModule).Hgm.GetPartialParamSet(uint64(num + 1)) { partialParamSet[string(k)] = v } assertMapSubset(t, tc.expected[num+1], partialParamSet) diff --git a/consensus/istanbul/backend/snapshot.go b/consensus/istanbul/backend/snapshot.go index 540eea6a1..911d67546 100644 --- a/consensus/istanbul/backend/snapshot.go +++ b/consensus/istanbul/backend/snapshot.go @@ -57,7 +57,7 @@ type Snapshot struct { } func effectiveParams(g gov.GovModule, number uint64) (epoch uint64, policy uint64, committeeSize uint64) { - pset := g.EffectiveParamSet(number) + pset := g.GetParamSet(number) epoch = pset.Epoch policy = pset.ProposerPolicy committeeSize = pset.CommitteeSize @@ -194,7 +194,7 @@ func (s *Snapshot) apply(headers []*types.Header, gov governance.Engine, govModu // Refresh proposers in Snapshot_N using previous proposersUpdateInterval block for N+1, if not updated yet. // because snapshot(num)'s ValSet = validators for num+1 - pset := govModule.EffectiveParamSet(number + 1) + pset := govModule.GetParamSet(number + 1) isSingle := (pset.GovernanceMode == "single") govNode := pset.GoverningNode diff --git a/kaiax/gov/README.md b/kaiax/gov/README.md index f0d864bee..3d42e896f 100644 --- a/kaiax/gov/README.md +++ b/kaiax/gov/README.md @@ -9,8 +9,8 @@ It's essentially a setting that can be adjusted to fine-tune how the network ope These parameters could control stuff like transaction fees, inflation rate, reward distribution, etc. A governance parameter has a name and a value; see [./param.go](./param.go). -`EffectiveParamSet(blockNum)` returns the governance parameter set that are used for mining the given block. -For example, if `EffectiveParamSet(10000)` is `{UnitPrice: 25 kei, ...}`, it indicates that the unit price will be 25 kei when mining the 10000th block. +`GetParamSet(blockNum)` returns the governance parameter set that are used for mining the given block. +For example, if `GetParamSet(10000)` is `{UnitPrice: 25 kei, ...}`, it indicates that the unit price will be 25 kei when mining the 10000th block. Here are the list of governance parameters: @@ -45,12 +45,12 @@ reward.useginicoeff: true This module utilizes [header governance](./headergov/README.md) and [contract governance](./contractgov/README.md) underneath to fetch the parameter set and to handle governance parameter updates. ``` -EffectiveParamSet(blockNum): +GetParamSet(blockNum): ret := defaultParamSet() merge ret with fallback (ChainConfig) - merge ret with HeaderGov.EffectiveParamSet(blockNum) + merge ret with HeaderGov.GetParamSet(blockNum) if blockNum is post-Kore-HF: - merge ret with ContractGov.EffectiveParamSet(blockNum) + merge ret with ContractGov.GetParamSet(blockNum) return ret ``` @@ -218,7 +218,7 @@ curl "http://localhost:8551" -X POST -H 'Content-Type: application/json' --data ## Getters -- `EffectiveParamSet(num)`: Returns the effective parameter set at the block `num`. +- `GetParamSet(num)`: Returns the effective parameter set at the block `num`. ``` - EffectiveParamSet(num) -> ParamSet + GetParamSet(num) -> ParamSet ``` diff --git a/kaiax/gov/contractgov/README.md b/kaiax/gov/contractgov/README.md index 95f02d3d9..263228f59 100644 --- a/kaiax/gov/contractgov/README.md +++ b/kaiax/gov/contractgov/README.md @@ -1,6 +1,7 @@ # kaiax/gov/contractgov This module is responsible for providing the governance parameter set from **contract governance** at a given block number. +This module is not meant to be used by any modules except for gov. ## Concepts @@ -9,7 +10,7 @@ Please read [gov module](../README.md) and [header governance](../headergov/READ ### Key Concepts - _GovParam contract_: a contract that stores the governance parameters. -- _effective parameter set at blockNum_: the governance parameter set that are effective when mining the given block. +- _parameter set at blockNum_: the governance parameter set that are effective when mining the given block. ### Contract governance @@ -84,13 +85,13 @@ curl "http://localhost:8551" -X POST -H 'Content-Type: application/json' --data ## Getters -- `EffectiveParamSet(num)`: Returns the effective parameter set at the block `num`. Those not specified in the contract are filled with defaults (defined [here](../param.go)). +- `GetParamSet(num)`: Returns the effective parameter set at the block `num`. Those not specified in the contract are filled with defaults (defined [here](../param.go)). ``` - EffectiveParamSet(num) -> ParamSet + GetParamSet(num) -> ParamSet ``` -- `EffectiveParamsPartial(num)`: Returns only the parameters effective by GovParam contract at the block `num`. It is used for assembling parameters in a gov module. +- `GetPartialParamSet(num)`: Returns only the parameters effective by GovParam contract at the block `num`. It is used for assembling parameters in a gov module. ``` - EffectiveParamsPartial(num) -> PartialParamSet + GetPartialParamSet(num) -> PartialParamSet ``` diff --git a/kaiax/gov/contractgov/impl/api.go b/kaiax/gov/contractgov/impl/api.go index 8b823c427..049472680 100644 --- a/kaiax/gov/contractgov/impl/api.go +++ b/kaiax/gov/contractgov/impl/api.go @@ -32,7 +32,7 @@ func (api *contractGovAPI) GetContractParams(num rpc.BlockNumber, govParam *comm govParamAddr = *govParam } else { // Use default GovParam address from headergov - govParamAddr = api.c.Hgm.EffectiveParamSet(blockNum).GovParamContract + govParamAddr = api.c.Hgm.GetParamSet(blockNum).GovParamContract } params, err := api.c.contractGetAllParamsAtFromAddr(blockNum, govParamAddr) diff --git a/kaiax/gov/contractgov/impl/error.go b/kaiax/gov/contractgov/impl/error.go index b88515785..018e93765 100644 --- a/kaiax/gov/contractgov/impl/error.go +++ b/kaiax/gov/contractgov/impl/error.go @@ -7,7 +7,7 @@ import ( var ( ErrNotReady = errors.New("ContractEngine is not ready") - ErrHeaderGovFail = errors.New("headerGov EffectiveParamSet() failed") + ErrHeaderGovFail = errors.New("headerGov GetParamSet() failed") ) func errInitNil(msg string) error { diff --git a/kaiax/gov/contractgov/impl/getter.go b/kaiax/gov/contractgov/impl/getter.go index ae299ea4d..a2fe8f01f 100644 --- a/kaiax/gov/contractgov/impl/getter.go +++ b/kaiax/gov/contractgov/impl/getter.go @@ -9,12 +9,12 @@ import ( "github.com/kaiachain/kaia/kaiax/gov" ) -// EffectiveParamSet returns default parameter set in case of the following errors: +// GetParamSet returns default parameter set in case of the following errors: // (1) contractgov is disabled (i.e., pre-Kore or GovParam address is zero) // (2) GovParam address is not set // (3) Contract call to GovParam failed // Invalid parameters in the contract (i.e., invalid parameter name or non-canonical value) are ignored. -func (c *contractGovModule) EffectiveParamSet(blockNum uint64) gov.ParamSet { +func (c *contractGovModule) GetParamSet(blockNum uint64) gov.ParamSet { m, err := c.contractGetAllParamsAt(blockNum) if err != nil { return *gov.GetDefaultGovernanceParamSet() @@ -31,7 +31,7 @@ func (c *contractGovModule) EffectiveParamSet(blockNum uint64) gov.ParamSet { return ret } -func (c *contractGovModule) EffectiveParamsPartial(blockNum uint64) gov.PartialParamSet { +func (c *contractGovModule) GetPartialParamSet(blockNum uint64) gov.PartialParamSet { m, err := c.contractGetAllParamsAt(blockNum) if err != nil { return nil @@ -85,7 +85,7 @@ func (c *contractGovModule) contractGetAllParamsAtFromAddr(blockNum uint64, addr } func (c *contractGovModule) contractAddrAt(blockNum uint64) (common.Address, error) { - headerParams := c.Hgm.EffectiveParamSet(blockNum) + headerParams := c.Hgm.GetParamSet(blockNum) return headerParams.GovParamContract, nil } diff --git a/kaiax/gov/contractgov/impl/getter_test.go b/kaiax/gov/contractgov/impl/getter_test.go index 6788f20f8..c3193397e 100644 --- a/kaiax/gov/contractgov/impl/getter_test.go +++ b/kaiax/gov/contractgov/impl/getter_test.go @@ -65,11 +65,11 @@ func prepareContractGovModule(t *testing.T, bc *blockchain.BlockChain, addr comm Hgm: mockHGM, }) require.Nil(t, err) - mockHGM.EXPECT().EffectiveParamSet(gomock.Any()).Return(gov.ParamSet{GovParamContract: addr}).AnyTimes() + mockHGM.EXPECT().GetParamSet(gomock.Any()).Return(gov.ParamSet{GovParamContract: addr}).AnyTimes() return cgm } -func TestEffectiveParamSet(t *testing.T) { +func TestGetParamSet(t *testing.T) { log.EnableLogForTest(log.LvlCrit, log.LvlError) paramName := string(gov.GovernanceUnitPrice) accounts, sim, addr, gp := createSimulateBackend(t) @@ -86,7 +86,7 @@ func TestEffectiveParamSet(t *testing.T) { require.NotNil(t, receipt) require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) - ps := cgm.EffectiveParamSet(activation.Uint64()) + ps := cgm.GetParamSet(activation.Uint64()) assert.NotNil(t, ps) assert.Equal(t, uint64(25), ps.UnitPrice) } @@ -102,7 +102,7 @@ func TestEffectiveParamSet(t *testing.T) { require.NotNil(t, receipt) require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) - ps := cgm.EffectiveParamSet(activation.Uint64()) + ps := cgm.GetParamSet(activation.Uint64()) assert.NotNil(t, ps) assert.Equal(t, uint64(125), ps.UnitPrice) } diff --git a/kaiax/gov/contractgov/interface.go b/kaiax/gov/contractgov/interface.go index c19474e71..5851f77de 100644 --- a/kaiax/gov/contractgov/interface.go +++ b/kaiax/gov/contractgov/interface.go @@ -10,6 +10,6 @@ type ContractGovModule interface { kaiax.BaseModule kaiax.JsonRpcModule - EffectiveParamSet(blockNum uint64) gov.ParamSet - EffectiveParamsPartial(blockNum uint64) gov.PartialParamSet + GetParamSet(blockNum uint64) gov.ParamSet + GetPartialParamSet(blockNum uint64) gov.PartialParamSet } diff --git a/kaiax/gov/contractgov/mock/contractgov_mock.go b/kaiax/gov/contractgov/mock/contractgov_mock.go index 495388f56..cab99f0f8 100644 --- a/kaiax/gov/contractgov/mock/contractgov_mock.go +++ b/kaiax/gov/contractgov/mock/contractgov_mock.go @@ -49,32 +49,32 @@ func (mr *MockContractGovModuleMockRecorder) APIs() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "APIs", reflect.TypeOf((*MockContractGovModule)(nil).APIs)) } -// EffectiveParamSet mocks base method. -func (m *MockContractGovModule) EffectiveParamSet(arg0 uint64) gov.ParamSet { +// GetParamSet mocks base method. +func (m *MockContractGovModule) GetParamSet(arg0 uint64) gov.ParamSet { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EffectiveParamSet", arg0) + ret := m.ctrl.Call(m, "GetParamSet", arg0) ret0, _ := ret[0].(gov.ParamSet) return ret0 } -// EffectiveParamSet indicates an expected call of EffectiveParamSet. -func (mr *MockContractGovModuleMockRecorder) EffectiveParamSet(arg0 interface{}) *gomock.Call { +// GetParamSet indicates an expected call of GetParamSet. +func (mr *MockContractGovModuleMockRecorder) GetParamSet(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EffectiveParamSet", reflect.TypeOf((*MockContractGovModule)(nil).EffectiveParamSet), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParamSet", reflect.TypeOf((*MockContractGovModule)(nil).GetParamSet), arg0) } -// EffectiveParamsPartial mocks base method. -func (m *MockContractGovModule) EffectiveParamsPartial(arg0 uint64) gov.PartialParamSet { +// GetPartialParamSet mocks base method. +func (m *MockContractGovModule) GetPartialParamSet(arg0 uint64) gov.PartialParamSet { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EffectiveParamsPartial", arg0) + ret := m.ctrl.Call(m, "GetPartialParamSet", arg0) ret0, _ := ret[0].(gov.PartialParamSet) return ret0 } -// EffectiveParamsPartial indicates an expected call of EffectiveParamsPartial. -func (mr *MockContractGovModuleMockRecorder) EffectiveParamsPartial(arg0 interface{}) *gomock.Call { +// GetPartialParamSet indicates an expected call of GetPartialParamSet. +func (mr *MockContractGovModuleMockRecorder) GetPartialParamSet(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EffectiveParamsPartial", reflect.TypeOf((*MockContractGovModule)(nil).EffectiveParamsPartial), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPartialParamSet", reflect.TypeOf((*MockContractGovModule)(nil).GetPartialParamSet), arg0) } // Start mocks base method. diff --git a/kaiax/gov/headergov/README.md b/kaiax/gov/headergov/README.md index f7cb4f19a..f6512770a 100644 --- a/kaiax/gov/headergov/README.md +++ b/kaiax/gov/headergov/README.md @@ -1,6 +1,7 @@ # kaiax/gov/headergov This module is responsible for providing the governance parameter set from **header governance** at a given block number. +This module is not meant to be used by any modules except for gov. ## Concepts @@ -12,7 +13,7 @@ Please read [gov module](../README.md) first. - _ratification_: votes in an epoch being declared as ratified (accepted). - _epoch_: a fixed period for header governance ratification. Defined in the genesis block. In Mainnet and Kairos, epoch is 604800 blocks (1 week). - _epoch index_: the index of the epoch, starting from 0. Given a block number `N`, its epoch index is `floor(N / epoch)`. In other words, all blocks in `[k*epoch, (k+1)*epoch - 1]` belong to the `k`-th epoch. -- _effective parameter set at blockNum_: the governance parameter set that are effective when mining the given block. +- _parameter set at blockNum_: the governance parameter set that are effective when mining the given block. ### Header governance @@ -50,13 +51,13 @@ It is worth noting that the effective time of the ratification is `(k+1)*epoch + ### Reading a parameter set -The effective parameter set at block `N` (in `k`-th epoch) is determined as follows: +The parameter set at block `N` (in `k`-th epoch) is determined as follows: - Collect all the ratified parameters from 0-th to `k-1`-th epoch. In case of duplication, recent ratification is prioritized. - `k-1` is calculated by [PrevEpochStart](./impl/getter.go#L41). - For each parameter, take the last ratified value. If a parameter has never been ratified, use the default value as a fallback. -This is the description of `EffectiveParamSet(N)`, which is implemented [here](./impl/getter.go#L9). +This is the description of `GetParamSet(N)`, which is implemented [here](./impl/getter.go#L9). For example, given `epoch=1000`, assume that `header` is as follows: @@ -455,13 +456,13 @@ curl "http://localhost:8551" -X POST -H 'Content-Type: application/json' --data ## Getters -- `EffectiveParamSet(num)`: Returns the effective parameter set at the block `num`. +- `GetParamSet(num)`: Returns the parameter set at the block `num`. ``` - EffectiveParamSet(num) -> ParamSet + GetParamSet(num) -> ParamSet ``` -- `EffectiveParamsPartial(num)`: Returns only the parameters effective by header governance, which is the union of `header.governance` from block 0 to `num`. It is used for assembling parameters in a gov module. +- `GetPartialParamSet(num)`: Returns only the parameters effective by header governance, which is the union of `header.governance` from block 0 to `num`. It is used for assembling parameters in a gov module. ``` - EffectiveParamsPartial(num) -> PartialParamSet + GetPartialParamSet(num) -> PartialParamSet ``` diff --git a/kaiax/gov/headergov/impl/api.go b/kaiax/gov/headergov/impl/api.go index 18dd63204..5411353df 100644 --- a/kaiax/gov/headergov/impl/api.go +++ b/kaiax/gov/headergov/impl/api.go @@ -50,7 +50,7 @@ func (api *headerGovAPI) Vote(name string, value any) (string, error) { var ( voter = api.h.nodeAddress blockNumber = api.h.Chain.CurrentBlock().NumberU64() - gp = api.h.EffectiveParamSet(blockNumber + 1) + gp = api.h.GetParamSet(blockNumber + 1) gMode = gp.GovernanceMode ) diff --git a/kaiax/gov/headergov/impl/consensus.go b/kaiax/gov/headergov/impl/consensus.go index 1566d3d66..605500183 100644 --- a/kaiax/gov/headergov/impl/consensus.go +++ b/kaiax/gov/headergov/impl/consensus.go @@ -186,12 +186,12 @@ func (h *headerGovModule) checkConsistency(blockNum uint64, vote headergov.VoteD return ErrGovParamNotContract } case gov.Kip71LowerBoundBaseFee: - params := h.EffectiveParamSet(blockNum) + params := h.GetParamSet(blockNum) if vote.Value().(uint64) > params.UpperBoundBaseFee { return ErrLowerBoundBaseFee } case gov.Kip71UpperBoundBaseFee: - params := h.EffectiveParamSet(blockNum) + params := h.GetParamSet(blockNum) if vote.Value().(uint64) < params.LowerBoundBaseFee { return ErrUpperBoundBaseFee } diff --git a/kaiax/gov/headergov/impl/consensus_test.go b/kaiax/gov/headergov/impl/consensus_test.go index 56d9da301..cadcc215c 100644 --- a/kaiax/gov/headergov/impl/consensus_test.go +++ b/kaiax/gov/headergov/impl/consensus_test.go @@ -154,6 +154,6 @@ func TestPrepareHeader(t *testing.T) { assert.NotNil(t, header.Governance) h.PostInsertBlock(types.NewBlockWithHeader(header)) - ps := h.EffectiveParamSet(2001) + ps := h.GetParamSet(2001) assert.Equal(t, ps.UnitPrice, uint64(100)) } diff --git a/kaiax/gov/headergov/impl/getter.go b/kaiax/gov/headergov/impl/getter.go index e5a4efd8d..023a7e5bf 100644 --- a/kaiax/gov/headergov/impl/getter.go +++ b/kaiax/gov/headergov/impl/getter.go @@ -8,7 +8,7 @@ import ( "golang.org/x/exp/maps" // TODO: use "maps" ) -func (h *headerGovModule) EffectiveParamSet(blockNum uint64) gov.ParamSet { +func (h *headerGovModule) GetParamSet(blockNum uint64) gov.ParamSet { h.mu.RLock() defer h.mu.RUnlock() @@ -21,7 +21,7 @@ func (h *headerGovModule) EffectiveParamSet(blockNum uint64) gov.ParamSet { return gp } -func (h *headerGovModule) EffectiveParamsPartial(blockNum uint64) gov.PartialParamSet { +func (h *headerGovModule) GetPartialParamSet(blockNum uint64) gov.PartialParamSet { prevEpochStart := PrevEpochStart(blockNum, h.epoch, h.isKoreHF(blockNum)) ret := make(gov.PartialParamSet) diff --git a/kaiax/gov/headergov/impl/getter_test.go b/kaiax/gov/headergov/impl/getter_test.go index e4d88757b..06b8800c2 100644 --- a/kaiax/gov/headergov/impl/getter_test.go +++ b/kaiax/gov/headergov/impl/getter_test.go @@ -53,7 +53,7 @@ func TestEffectiveParams(t *testing.T) { h.HandleGov(num, g) } - gp := h.EffectiveParamSet(tc.blockNum) + gp := h.GetParamSet(tc.blockNum) assert.Equal(t, tc.expectedPrice, gp.UnitPrice) }) } @@ -85,7 +85,7 @@ func TestEffectiveParamsPartial(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Block %d", tc.blockNum), func(t *testing.T) { - gp := h.EffectiveParamsPartial(tc.blockNum) + gp := h.GetPartialParamSet(tc.blockNum) assert.Equal(t, tc.expectedPrice, gp[gov.GovernanceUnitPrice]) }) } diff --git a/kaiax/gov/headergov/interface.go b/kaiax/gov/headergov/interface.go index 4d9918b54..ccad93781 100644 --- a/kaiax/gov/headergov/interface.go +++ b/kaiax/gov/headergov/interface.go @@ -14,8 +14,8 @@ type HeaderGovModule interface { kaiax.ExecutionModule kaiax.RewindableModule - EffectiveParamSet(blockNum uint64) gov.ParamSet - EffectiveParamsPartial(blockNum uint64) gov.PartialParamSet + GetParamSet(blockNum uint64) gov.ParamSet + GetPartialParamSet(blockNum uint64) gov.PartialParamSet NodeAddress() common.Address PushMyVotes(vote VoteData) } diff --git a/kaiax/gov/headergov/mock/headergov_mock.go b/kaiax/gov/headergov/mock/headergov_mock.go index 2348d48c6..774665d4d 100644 --- a/kaiax/gov/headergov/mock/headergov_mock.go +++ b/kaiax/gov/headergov/mock/headergov_mock.go @@ -53,46 +53,46 @@ func (mr *MockHeaderGovModuleMockRecorder) APIs() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "APIs", reflect.TypeOf((*MockHeaderGovModule)(nil).APIs)) } -// EffectiveParamSet mocks base method. -func (m *MockHeaderGovModule) EffectiveParamSet(arg0 uint64) gov.ParamSet { +// FinalizeHeader mocks base method. +func (m *MockHeaderGovModule) FinalizeHeader(arg0 *types.Header, arg1 *state.StateDB, arg2 []*types.Transaction, arg3 []*types.Receipt) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EffectiveParamSet", arg0) - ret0, _ := ret[0].(gov.ParamSet) + ret := m.ctrl.Call(m, "FinalizeHeader", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) return ret0 } -// EffectiveParamSet indicates an expected call of EffectiveParamSet. -func (mr *MockHeaderGovModuleMockRecorder) EffectiveParamSet(arg0 interface{}) *gomock.Call { +// FinalizeHeader indicates an expected call of FinalizeHeader. +func (mr *MockHeaderGovModuleMockRecorder) FinalizeHeader(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EffectiveParamSet", reflect.TypeOf((*MockHeaderGovModule)(nil).EffectiveParamSet), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinalizeHeader", reflect.TypeOf((*MockHeaderGovModule)(nil).FinalizeHeader), arg0, arg1, arg2, arg3) } -// EffectiveParamsPartial mocks base method. -func (m *MockHeaderGovModule) EffectiveParamsPartial(arg0 uint64) gov.PartialParamSet { +// GetParamSet mocks base method. +func (m *MockHeaderGovModule) GetParamSet(arg0 uint64) gov.ParamSet { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EffectiveParamsPartial", arg0) - ret0, _ := ret[0].(gov.PartialParamSet) + ret := m.ctrl.Call(m, "GetParamSet", arg0) + ret0, _ := ret[0].(gov.ParamSet) return ret0 } -// EffectiveParamsPartial indicates an expected call of EffectiveParamsPartial. -func (mr *MockHeaderGovModuleMockRecorder) EffectiveParamsPartial(arg0 interface{}) *gomock.Call { +// GetParamSet indicates an expected call of GetParamSet. +func (mr *MockHeaderGovModuleMockRecorder) GetParamSet(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EffectiveParamsPartial", reflect.TypeOf((*MockHeaderGovModule)(nil).EffectiveParamsPartial), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParamSet", reflect.TypeOf((*MockHeaderGovModule)(nil).GetParamSet), arg0) } -// FinalizeHeader mocks base method. -func (m *MockHeaderGovModule) FinalizeHeader(arg0 *types.Header, arg1 *state.StateDB, arg2 []*types.Transaction, arg3 []*types.Receipt) error { +// GetPartialParamSet mocks base method. +func (m *MockHeaderGovModule) GetPartialParamSet(arg0 uint64) gov.PartialParamSet { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FinalizeHeader", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(error) + ret := m.ctrl.Call(m, "GetPartialParamSet", arg0) + ret0, _ := ret[0].(gov.PartialParamSet) return ret0 } -// FinalizeHeader indicates an expected call of FinalizeHeader. -func (mr *MockHeaderGovModuleMockRecorder) FinalizeHeader(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +// GetPartialParamSet indicates an expected call of GetPartialParamSet. +func (mr *MockHeaderGovModuleMockRecorder) GetPartialParamSet(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinalizeHeader", reflect.TypeOf((*MockHeaderGovModule)(nil).FinalizeHeader), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPartialParamSet", reflect.TypeOf((*MockHeaderGovModule)(nil).GetPartialParamSet), arg0) } // NodeAddress mocks base method. diff --git a/kaiax/gov/impl/api.go b/kaiax/gov/impl/api.go index 58c016b95..7ec1bfd16 100644 --- a/kaiax/gov/impl/api.go +++ b/kaiax/gov/impl/api.go @@ -138,7 +138,7 @@ func getParams(g *GovModule, num *rpc.BlockNumber) (gov.PartialParamSet, error) } rule := g.Chain.Config().Rules(new(big.Int).SetUint64(blockNumber)) - gp := g.EffectiveParamSet(blockNumber) + gp := g.GetParamSet(blockNumber) gp = patchDeprecatedParams(gp, rule) ret := gp.ToMap() return ret, nil diff --git a/kaiax/gov/impl/getter.go b/kaiax/gov/impl/getter.go index ec42ec892..7aeda18ed 100644 --- a/kaiax/gov/impl/getter.go +++ b/kaiax/gov/impl/getter.go @@ -4,7 +4,7 @@ import ( "github.com/kaiachain/kaia/kaiax/gov" ) -func (m *GovModule) EffectiveParamSet(blockNum uint64) gov.ParamSet { +func (m *GovModule) GetParamSet(blockNum uint64) gov.ParamSet { ret := gov.GetDefaultGovernanceParamSet() p0 := m.Fallback @@ -12,13 +12,13 @@ func (m *GovModule) EffectiveParamSet(blockNum uint64) gov.ParamSet { ret.Set(k, v) } - p1 := m.Hgm.EffectiveParamsPartial(blockNum) + p1 := m.Hgm.GetPartialParamSet(blockNum) for k, v := range p1 { ret.Set(k, v) } if m.isKoreHF(blockNum) { - p2 := m.Cgm.EffectiveParamsPartial(blockNum) + p2 := m.Cgm.GetPartialParamSet(blockNum) for k, v := range p2 { ret.Set(k, v) } diff --git a/kaiax/gov/impl/getter_test.go b/kaiax/gov/impl/getter_test.go index c094cc938..99f8d5c8b 100644 --- a/kaiax/gov/impl/getter_test.go +++ b/kaiax/gov/impl/getter_test.go @@ -38,7 +38,7 @@ func newGovModuleMock(t *testing.T, config *params.ChainConfig) (*headergov_mock return hgm, cgm, m } -func TestEffectiveParamSet(t *testing.T) { +func TestGetParamSet(t *testing.T) { var ( defaultVal = uint64(250e9) headerGovVal = uint64(123) @@ -48,23 +48,23 @@ func TestEffectiveParamSet(t *testing.T) { t.Run("pre-kore", func(t *testing.T) { hgm, cgm, m := newGovModuleMock(t, ¶ms.ChainConfig{KoreCompatibleBlock: nil}) t.Run("default", func(t *testing.T) { - hgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(nil) - cgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(nil) - ps := m.EffectiveParamSet(1) + hgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(nil) + cgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(nil) + ps := m.GetParamSet(1) assert.Equal(t, defaultVal, ps.UnitPrice) }) t.Run("headergov", func(t *testing.T) { - hgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: headerGovVal}) - cgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(gov.PartialParamSet{}) - ps := m.EffectiveParamSet(1) + hgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: headerGovVal}) + cgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(gov.PartialParamSet{}) + ps := m.GetParamSet(1) assert.Equal(t, headerGovVal, ps.UnitPrice) }) t.Run("contractgov ignored", func(t *testing.T) { - hgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: headerGovVal}) - cgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: contractGovVal}) - ps := m.EffectiveParamSet(1) + hgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: headerGovVal}) + cgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: contractGovVal}) + ps := m.GetParamSet(1) assert.Equal(t, headerGovVal, ps.UnitPrice) }) }) @@ -73,23 +73,23 @@ func TestEffectiveParamSet(t *testing.T) { hgm, cgm, m := newGovModuleMock(t, ¶ms.ChainConfig{KoreCompatibleBlock: big.NewInt(0)}) t.Run("default", func(t *testing.T) { - hgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(nil) - cgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(nil) - ps := m.EffectiveParamSet(1) + hgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(nil) + cgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(nil) + ps := m.GetParamSet(1) assert.Equal(t, defaultVal, ps.UnitPrice) }) t.Run("headergov", func(t *testing.T) { - hgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: headerGovVal}) - cgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(gov.PartialParamSet{}) - ps := m.EffectiveParamSet(1) + hgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: headerGovVal}) + cgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(gov.PartialParamSet{}) + ps := m.GetParamSet(1) assert.Equal(t, headerGovVal, ps.UnitPrice) }) t.Run("contractgov", func(t *testing.T) { - hgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: headerGovVal}) - cgm.EXPECT().EffectiveParamsPartial(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: contractGovVal}) - ps := m.EffectiveParamSet(1) + hgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: headerGovVal}) + cgm.EXPECT().GetPartialParamSet(gomock.Any()).Return(gov.PartialParamSet{gov.GovernanceUnitPrice: contractGovVal}) + ps := m.GetParamSet(1) assert.Equal(t, contractGovVal, ps.UnitPrice) }) }) diff --git a/kaiax/gov/interface.go b/kaiax/gov/interface.go index 7828d9483..05a70b838 100644 --- a/kaiax/gov/interface.go +++ b/kaiax/gov/interface.go @@ -12,5 +12,5 @@ type GovModule interface { kaiax.ExecutionModule kaiax.RewindableModule - EffectiveParamSet(blockNum uint64) ParamSet + GetParamSet(blockNum uint64) ParamSet } diff --git a/kaiax/gov/mock/govmodule_mock.go b/kaiax/gov/mock/govmodule_mock.go index 733084c09..5395d68d2 100644 --- a/kaiax/gov/mock/govmodule_mock.go +++ b/kaiax/gov/mock/govmodule_mock.go @@ -52,20 +52,6 @@ func (mr *MockGovModuleMockRecorder) APIs() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "APIs", reflect.TypeOf((*MockGovModule)(nil).APIs)) } -// EffectiveParamSet mocks base method. -func (m *MockGovModule) EffectiveParamSet(arg0 uint64) gov.ParamSet { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EffectiveParamSet", arg0) - ret0, _ := ret[0].(gov.ParamSet) - return ret0 -} - -// EffectiveParamSet indicates an expected call of EffectiveParamSet. -func (mr *MockGovModuleMockRecorder) EffectiveParamSet(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EffectiveParamSet", reflect.TypeOf((*MockGovModule)(nil).EffectiveParamSet), arg0) -} - // FinalizeHeader mocks base method. func (m *MockGovModule) FinalizeHeader(arg0 *types.Header, arg1 *state.StateDB, arg2 []*types.Transaction, arg3 []*types.Receipt) error { m.ctrl.T.Helper() @@ -80,6 +66,20 @@ func (mr *MockGovModuleMockRecorder) FinalizeHeader(arg0, arg1, arg2, arg3 inter return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinalizeHeader", reflect.TypeOf((*MockGovModule)(nil).FinalizeHeader), arg0, arg1, arg2, arg3) } +// GetParamSet mocks base method. +func (m *MockGovModule) GetParamSet(arg0 uint64) gov.ParamSet { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetParamSet", arg0) + ret0, _ := ret[0].(gov.ParamSet) + return ret0 +} + +// GetParamSet indicates an expected call of GetParamSet. +func (mr *MockGovModuleMockRecorder) GetParamSet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParamSet", reflect.TypeOf((*MockGovModule)(nil).GetParamSet), arg0) +} + // PostInsertBlock mocks base method. func (m *MockGovModule) PostInsertBlock(arg0 *types.Block) error { m.ctrl.T.Helper() diff --git a/kaiax/reward/config.go b/kaiax/reward/config.go index 312b32610..dfb4ecfdd 100644 --- a/kaiax/reward/config.go +++ b/kaiax/reward/config.go @@ -45,7 +45,7 @@ type RewardConfig struct { // TODO-kaiax: Restore to gov.GovModule after introducing kaiax/gov type GovModule interface { - EffectiveParamSet(blockNum uint64) gov.ParamSet + GetParamSet(blockNum uint64) gov.ParamSet } func NewRewardConfig(chainConfig *params.ChainConfig, govModule GovModule, header *types.Header) (*RewardConfig, error) { @@ -54,7 +54,7 @@ func NewRewardConfig(chainConfig *params.ChainConfig, govModule GovModule, heade rc.Rules = chainConfig.Rules(header.Number) rc.Rewardbase = header.Rewardbase - paramset := govModule.EffectiveParamSet(header.Number.Uint64()) + paramset := govModule.GetParamSet(header.Number.Uint64()) rc.IsSimple = paramset.ProposerPolicy != uint64(istanbul.WeightedRandom) rc.UnitPrice = new(big.Int).SetUint64(paramset.UnitPrice) rc.MintingAmount = new(big.Int).Set(paramset.MintingAmount) diff --git a/kaiax/reward/impl/init_test.go b/kaiax/reward/impl/init_test.go index 0e1358058..4b9543c0d 100644 --- a/kaiax/reward/impl/init_test.go +++ b/kaiax/reward/impl/init_test.go @@ -100,7 +100,7 @@ func makeTestRewardModule(t *testing.T, chain.EXPECT().GetReceiptsByBlockHash(block.Hash()).Return(receipts).AnyTimes() chain.EXPECT().Engine().Return(engine).AnyTimes() engine.EXPECT().Author(gomock.Any()).Return(common.HexToAddress("0xeee"), nil).AnyTimes() // Author is different from Rewardbase - mGov.EXPECT().EffectiveParamSet(header.Number.Uint64()).Return(paramset).AnyTimes() + mGov.EXPECT().GetParamSet(header.Number.Uint64()).Return(paramset).AnyTimes() mStaking.EXPECT().GetStakingInfo(gomock.Any()).Return(stakingInfo, nil).AnyTimes() return r diff --git a/kaiax/supply/impl/testutil_test.go b/kaiax/supply/impl/testutil_test.go index c68a2363e..d34d76313 100644 --- a/kaiax/supply/impl/testutil_test.go +++ b/kaiax/supply/impl/testutil_test.go @@ -320,7 +320,7 @@ func setupMockEngine(engine *consensus_mock.MockEngine, chain *blockchain.BlockC } func setupMockGov(mGov *gov_mock.MockGovModule, config *params.ChainConfig) { - mGov.EXPECT().EffectiveParamSet(gomock.Any()).DoAndReturn(func(num uint64) (gov.ParamSet, error) { + mGov.EXPECT().GetParamSet(gomock.Any()).DoAndReturn(func(num uint64) (gov.ParamSet, error) { p0 := gov.ParamSet{ ProposerPolicy: uint64(config.Istanbul.ProposerPolicy), UnitPrice: config.UnitPrice, diff --git a/node/cn/api_backend.go b/node/cn/api_backend.go index 6ef22753f..aa97dedf5 100644 --- a/node/cn/api_backend.go +++ b/node/cn/api_backend.go @@ -316,7 +316,7 @@ func (b *CNAPIBackend) SuggestTipCap(ctx context.Context) (*big.Int, error) { func (b *CNAPIBackend) UpperBoundGasPrice(ctx context.Context) *big.Int { bignum := b.CurrentBlock().Number() - pset := b.cn.govModule.EffectiveParamSet(bignum.Uint64() + 1) + pset := b.cn.govModule.GetParamSet(bignum.Uint64() + 1) if b.cn.chainConfig.IsMagmaForkEnabled(bignum) { return new(big.Int).SetUint64(pset.UpperBoundBaseFee) } else { @@ -326,7 +326,7 @@ func (b *CNAPIBackend) UpperBoundGasPrice(ctx context.Context) *big.Int { func (b *CNAPIBackend) LowerBoundGasPrice(ctx context.Context) *big.Int { bignum := b.CurrentBlock().Number() - pset := b.cn.govModule.EffectiveParamSet(bignum.Uint64() + 1) + pset := b.cn.govModule.GetParamSet(bignum.Uint64() + 1) if b.cn.chainConfig.IsMagmaForkEnabled(bignum) { return new(big.Int).SetUint64(pset.LowerBoundBaseFee) } else { diff --git a/node/cn/api_backend_test.go b/node/cn/api_backend_test.go index ed4d85915..c38eba7cc 100644 --- a/node/cn/api_backend_test.go +++ b/node/cn/api_backend_test.go @@ -808,7 +808,7 @@ func headerGovSetHeadTest(t *testing.T, tt *rewindTest) { assert.Nil(t, err) // Before setHead - assert.Equal(t, newMintingAmount, govModule.EffectiveParamSet(appliedGovBlockNum).MintingAmount.String()) + assert.Equal(t, newMintingAmount, govModule.GetParamSet(appliedGovBlockNum).MintingAmount.String()) // Set the head of the chain back to the requested number err = doSetHead(chain, chain.Engine(), gpo, tt.setheadBlock) @@ -825,7 +825,7 @@ func headerGovSetHeadTest(t *testing.T, tt *rewindTest) { } // After setHead // governance db and cachelookup - assert.Equal(t, oldMintingAmount, govModule.EffectiveParamSet(appliedGovBlockNum).MintingAmount.String()) + assert.Equal(t, oldMintingAmount, govModule.GetParamSet(appliedGovBlockNum).MintingAmount.String()) // snapshot db lookup _, err = db.ReadIstanbulSnapshot(snap.Hash) @@ -843,5 +843,5 @@ func headerGovSetHeadTest(t *testing.T, tt *rewindTest) { t.Errorf("Head block mismatch!!: have %d, want %d", head.NumberU64(), tt.expHeadBlock) } // After setHead and sync - assert.Equal(t, newMintingAmount, govModule.EffectiveParamSet(appliedGovBlockNum).MintingAmount.String()) + assert.Equal(t, newMintingAmount, govModule.GetParamSet(appliedGovBlockNum).MintingAmount.String()) } diff --git a/node/cn/backend.go b/node/cn/backend.go index 23fdcad3d..a5b7a0ccb 100644 --- a/node/cn/backend.go +++ b/node/cn/backend.go @@ -325,7 +325,7 @@ func New(ctx *node.ServiceContext, config *Config) (*CN, error) { blockchain.InitDeriveShaWithGov(cn.chainConfig, mGov) // Synchronize proposerpolicy & useGiniCoeff - pset := mGov.EffectiveParamSet(bc.CurrentBlock().NumberU64() + 1) + pset := mGov.GetParamSet(bc.CurrentBlock().NumberU64() + 1) if cn.blockchain.Config().Istanbul != nil { cn.blockchain.Config().Istanbul.ProposerPolicy = pset.ProposerPolicy } diff --git a/node/cn/gasprice/feehistory.go b/node/cn/gasprice/feehistory.go index 31a388ac7..c854f972b 100644 --- a/node/cn/gasprice/feehistory.go +++ b/node/cn/gasprice/feehistory.go @@ -102,7 +102,7 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { isCurrBlockMagma = chainconfig.IsMagmaForkEnabled(big.NewInt(int64(bf.blockNumber))) isNextBlockMagma = chainconfig.IsMagmaForkEnabled(big.NewInt(int64(bf.blockNumber + 1))) - pset = oracle.govModule.EffectiveParamSet(bf.blockNumber + 1) + pset = oracle.govModule.GetParamSet(bf.blockNumber + 1) kip71Config = pset.ToKip71Config() ) if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil { diff --git a/node/cn/gasprice/feehistory_test.go b/node/cn/gasprice/feehistory_test.go index 332d87b4e..6308846b1 100644 --- a/node/cn/gasprice/feehistory_test.go +++ b/node/cn/gasprice/feehistory_test.go @@ -94,8 +94,8 @@ func TestFeeHistory(t *testing.T) { } oracle = NewOracle(backend, config, nil, govModule) - atMagmaPset = oracle.govModule.EffectiveParamSet(uint64(magmaBlock)) - afterMagmaPset = oracle.govModule.EffectiveParamSet(uint64(magmaBlock + 1)) + atMagmaPset = oracle.govModule.GetParamSet(uint64(magmaBlock)) + afterMagmaPset = oracle.govModule.GetParamSet(uint64(magmaBlock + 1)) beforeMagmaExpectedBaseFee = big.NewInt(0) atMagmaExpectedBaseFee = big.NewInt(int64(atMagmaPset.LowerBoundBaseFee)) diff --git a/node/cn/gasprice/gasprice.go b/node/cn/gasprice/gasprice.go index 62710a426..b52b47073 100644 --- a/node/cn/gasprice/gasprice.go +++ b/node/cn/gasprice/gasprice.go @@ -338,7 +338,7 @@ func (oracle *Oracle) getBlockValues(ctx context.Context, blockNum uint64, limit // paying any tip is unnecessary. It returns true when the head block is after Magma fork // and the next base fee is at the lower bound. func (oracle *Oracle) isRelaxedNetwork(header *types.Header) bool { - pset := oracle.govModule.EffectiveParamSet(header.Number.Uint64() + 1) + pset := oracle.govModule.GetParamSet(header.Number.Uint64() + 1) kip71 := pset.ToKip71Config() nextBaseFee := misc.NextMagmaBlockBaseFee(header, kip71) return nextBaseFee.Cmp(big.NewInt(int64(pset.LowerBoundBaseFee))) <= 0 diff --git a/node/cn/gasprice/gasprice_test.go b/node/cn/gasprice/gasprice_test.go index e71b23a64..5f458e8ae 100644 --- a/node/cn/gasprice/gasprice_test.go +++ b/node/cn/gasprice/gasprice_test.go @@ -221,7 +221,7 @@ func TestGasPrice_SuggestPrice(t *testing.T) { defer testBackend.teardown() chainConfig := testBackend.ChainConfig() mockGov := mock_gov.NewMockGovModule(gomock.NewController(t)) - mockGov.EXPECT().EffectiveParamSet(gomock.Any()).Return(gov.ParamSet{UnitPrice: 0}).Times(1) + mockGov.EXPECT().GetParamSet(gomock.Any()).Return(gov.ParamSet{UnitPrice: 0}).Times(1) txPoolWith0 := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, chainConfig, testBackend.chain, mockGov) oracle := NewOracle(mockBackend, params, txPoolWith0, mockGov) @@ -235,7 +235,7 @@ func TestGasPrice_SuggestPrice(t *testing.T) { assert.Nil(t, err) params = Config{} - mockGov.EXPECT().EffectiveParamSet(gomock.Any()).Return(gov.ParamSet{UnitPrice: 25}).Times(1) + mockGov.EXPECT().GetParamSet(gomock.Any()).Return(gov.ParamSet{UnitPrice: 25}).Times(1) mockBackend.EXPECT().ChainConfig().Return(chainConfig).Times(2) txPoolWith25 := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, chainConfig, testBackend.chain, mockGov) oracle = NewOracle(mockBackend, params, txPoolWith25, mockGov) @@ -288,7 +288,7 @@ func TestSuggestTipCap(t *testing.T) { chainConfig := testBackend.ChainConfig() if c.isBusy { mockGov := mock_gov.NewMockGovModule(gomock.NewController(t)) - mockGov.EXPECT().EffectiveParamSet(gomock.Any()).Return(gov.ParamSet{UnitPrice: testBackend.ChainConfig().UnitPrice, LowerBoundBaseFee: math.MaxUint64}).AnyTimes() + mockGov.EXPECT().GetParamSet(gomock.Any()).Return(gov.ParamSet{UnitPrice: testBackend.ChainConfig().UnitPrice, LowerBoundBaseFee: math.MaxUint64}).AnyTimes() testGov = mockGov } txPool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, chainConfig, testBackend.chain, testGov) diff --git a/node/sc/mainbridge_test.go b/node/sc/mainbridge_test.go index 76883da90..1934f0506 100644 --- a/node/sc/mainbridge_test.go +++ b/node/sc/mainbridge_test.go @@ -113,7 +113,7 @@ func testBlockChain(t *testing.T) *blockchain.BlockChain { func testTxPool(t *testing.T, dataDir string, bc *blockchain.BlockChain) *blockchain.TxPool { blockchain.DefaultTxPoolConfig.Journal = path.Join(dataDir, blockchain.DefaultTxPoolConfig.Journal) mockGov := gov_mock.NewMockGovModule(gomock.NewController(t)) - mockGov.EXPECT().EffectiveParamSet(gomock.Any()).Return(gov.ParamSet{UnitPrice: bc.Config().UnitPrice}).AnyTimes() + mockGov.EXPECT().GetParamSet(gomock.Any()).Return(gov.ParamSet{UnitPrice: bc.Config().UnitPrice}).AnyTimes() return blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bc.Config(), bc, mockGov) } diff --git a/tests/gov_contract_test.go b/tests/gov_contract_test.go index 03f483a40..6efbc667b 100644 --- a/tests/gov_contract_test.go +++ b/tests/gov_contract_test.go @@ -125,7 +125,7 @@ func TestGovernance_GovModule(t *testing.T) { if govBytes := ev.Block.Header().Governance; len(govBytes) > 0 { govBlock = num // stopBlock is the epoch block, so we stop when receiving it - // otherwise, EffectiveParams(stopBlock) may fail + // otherwise, GetParamSet(stopBlock) may fail stopBlock = govBlock + 5 stopBlock = stopBlock - (stopBlock % config.Istanbul.Epoch) t.Logf("Governance at block=%2d, stopBlock=%2d, gov=%v", num, stopBlock, hexutil.Encode(govBytes)) @@ -140,10 +140,10 @@ func TestGovernance_GovModule(t *testing.T) { } } - // 2. test EffectiveParamSet(): Validate historic params from both Engines + // 2. test GetParamSet(): Validate historic params from both Engines for num := uint64(0); num < stopBlock; num++ { - govVal := govModule.EffectiveParamSet(num).CommitteeSize - contractVal := govModule.Cgm.EffectiveParamSet(num).CommitteeSize + govVal := govModule.GetParamSet(num).CommitteeSize + contractVal := govModule.Cgm.GetParamSet(num).CommitteeSize if num <= govBlock+1 { // ContractEngine disabled assert.Equal(t, oldVal, govVal) diff --git a/tests/gov_test.go b/tests/gov_test.go index bc961da65..843febd0e 100644 --- a/tests/gov_test.go +++ b/tests/gov_test.go @@ -63,7 +63,7 @@ func TestMainnetGenesisGovernance(t *testing.T) { "reward.useginicoeff": true, } - pset := govModule.EffectiveParamSet(0) + pset := govModule.GetParamSet(0) govParamsMap := pset.ToMap() assert.Equal(t, len(genesisParamsMap), len(govParamsMap)) diff --git a/work/worker.go b/work/worker.go index 1afd6e5b7..030aadf7b 100644 --- a/work/worker.go +++ b/work/worker.go @@ -554,7 +554,7 @@ func (self *worker) commitNewWork() { if self.config.IsMagmaForkEnabled(nextBlockNum) { // NOTE-Kaia NextBlockBaseFee needs the header of parent, self.chain.CurrentBlock // So above code, TxPool().Pending(), is separated with this and can be refactored later. - pset := self.govModule.EffectiveParamSet(nextBlockNum.Uint64()) + pset := self.govModule.GetParamSet(nextBlockNum.Uint64()) nextBaseFee = misc.NextMagmaBlockBaseFee(parent.Header(), pset.ToKip71Config()) pending = types.FilterTransactionWithBaseFee(pending, nextBaseFee) } From d4c1154b7c6279cb8d601488d05decc646881df8 Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Mon, 16 Dec 2024 16:27:00 +0900 Subject: [PATCH 02/12] Add GetChainConfig unittest --- kaiax/gov/impl/api.go | 6 ++-- kaiax/gov/impl/api_test.go | 66 +++++++++++++++++++++++++++++++++++++ kaiax/gov/impl/init_test.go | 16 +++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 kaiax/gov/impl/api_test.go diff --git a/kaiax/gov/impl/api.go b/kaiax/gov/impl/api.go index 7ec1bfd16..887c950a5 100644 --- a/kaiax/gov/impl/api.go +++ b/kaiax/gov/impl/api.go @@ -87,10 +87,10 @@ func getChainConfig(g *GovModule, num *rpc.BlockNumber) *params.ChainConfig { blocknum = num.Uint64() } - pset := g.EffectiveParamSet(blocknum) - rule := g.Chain.Config().Rules(new(big.Int).SetUint64(blocknum)) - pset = patchDeprecatedParams(pset, rule) latestConfig := g.Chain.Config() + pset := g.GetParamSet(blocknum) + rule := latestConfig.Rules(new(big.Int).SetUint64(blocknum)) + pset = patchDeprecatedParams(pset, rule) config := pset.ToGovParamSet().ToChainConfig() config.ChainID = latestConfig.ChainID config.IstanbulCompatibleBlock = latestConfig.IstanbulCompatibleBlock diff --git a/kaiax/gov/impl/api_test.go b/kaiax/gov/impl/api_test.go new file mode 100644 index 000000000..d787ff567 --- /dev/null +++ b/kaiax/gov/impl/api_test.go @@ -0,0 +1,66 @@ +package impl + +import ( + "math/big" + "reflect" + "strings" + "testing" + + "github.com/kaiachain/kaia/kaiax/gov" + contractgov_mock "github.com/kaiachain/kaia/kaiax/gov/contractgov/mock" + headergov_mock "github.com/kaiachain/kaia/kaiax/gov/headergov/mock" + "github.com/kaiachain/kaia/networks/rpc" + "github.com/kaiachain/kaia/params" + "github.com/kaiachain/kaia/work/mocks" + "github.com/stretchr/testify/assert" +) + +func newKaiaAPI(t *testing.T, chainConfig *params.ChainConfig) (*KaiaAPI, *mocks.MockBlockChain, *headergov_mock.MockHeaderGovModule, *contractgov_mock.MockContractGovModule) { + h, mockChain, mockHgm, mockCgm := newGovModule(t, chainConfig) + return NewKaiaAPI(h), mockChain, mockHgm, mockCgm +} + +func TestAPI_kaia_getChainConfig(t *testing.T) { + var ( + latestGenesisConfig = params.MainnetChainConfig.Copy() + api, mockChain, mockHgm, mockCgm = newKaiaAPI(t, latestGenesisConfig) + num = rpc.BlockNumber(0) + ) + + mockHgm.EXPECT().GetPartialParamSet(uint64(0)).Return(gov.PartialParamSet{}).Times(1) + mockCgm.EXPECT().GetPartialParamSet(uint64(0)).Return(gov.PartialParamSet{}).Times(1) + mockChain.EXPECT().Config().Return(latestGenesisConfig).Times(2) // isKore, getChainConfig + + // Set all *CompatibleBlock fields to zero. + { + v := reflect.ValueOf(latestGenesisConfig).Elem() + ty := v.Type() + + for i := 0; i < ty.NumField(); i++ { + field := ty.Field(i) + if strings.HasSuffix(field.Name, "CompatibleBlock") { + fieldValue := v.Field(i) + if fieldValue.Type() == reflect.TypeOf((*big.Int)(nil)) { + fieldValue.Set(reflect.ValueOf(big.NewInt(0))) + } + } + } + } + + // Check if there is any missing Hardfork block in the API result + { + cc := api.GetChainConfig(&num) + v := reflect.ValueOf(cc).Elem() + ty := v.Type() + + for i := 0; i < ty.NumField(); i++ { + field := ty.Field(i) + if strings.HasSuffix(field.Name, "CompatibleBlock") { + fieldValue := v.Field(i) + if fieldValue.Type() == reflect.TypeOf((*big.Int)(nil)) { + assert.Equal(t, fieldValue.Interface().(*big.Int).String(), big.NewInt(0).String()) + } + } + } + } +} diff --git a/kaiax/gov/impl/init_test.go b/kaiax/gov/impl/init_test.go index d7b2c3985..3a9219f92 100644 --- a/kaiax/gov/impl/init_test.go +++ b/kaiax/gov/impl/init_test.go @@ -4,12 +4,28 @@ import ( "math/big" "testing" + gomock "github.com/golang/mock/gomock" "github.com/kaiachain/kaia/common" "github.com/kaiachain/kaia/kaiax/gov" + contractgov_mock "github.com/kaiachain/kaia/kaiax/gov/contractgov/mock" + headergov_mock "github.com/kaiachain/kaia/kaiax/gov/headergov/mock" "github.com/kaiachain/kaia/params" + "github.com/kaiachain/kaia/work/mocks" "github.com/stretchr/testify/assert" ) +func newGovModule(t *testing.T, chainConfig *params.ChainConfig) (*GovModule, *mocks.MockBlockChain, *headergov_mock.MockHeaderGovModule, *contractgov_mock.MockContractGovModule) { + govModule := NewGovModule() + mockChain := mocks.NewMockBlockChain(gomock.NewController(t)) + mockHgm := headergov_mock.NewMockHeaderGovModule(gomock.NewController(t)) + mockCgm := contractgov_mock.NewMockContractGovModule(gomock.NewController(t)) + + govModule.Chain = mockChain + govModule.Hgm = mockHgm + govModule.Cgm = mockCgm + return govModule, mockChain, mockHgm, mockCgm +} + func TestChainConfigFallback(t *testing.T) { tests := []struct { desc string From 6432e21d3c0d8c3bca23707b8f88d4bf00462cf9 Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Mon, 16 Dec 2024 16:27:06 +0900 Subject: [PATCH 03/12] Add missing header log --- kaiax/gov/headergov/impl/init.go | 1 + 1 file changed, 1 insertion(+) diff --git a/kaiax/gov/headergov/impl/init.go b/kaiax/gov/headergov/impl/init.go index c2afa6181..ca660a2d2 100644 --- a/kaiax/gov/headergov/impl/init.go +++ b/kaiax/gov/headergov/impl/init.go @@ -158,6 +158,7 @@ func (h *headerGovModule) scanAllVotesInEpoch(epochIdx uint64) map[uint64]header for blockNum := rangeStart; blockNum < rangeEnd; blockNum++ { header := h.Chain.GetHeaderByNumber(blockNum) if header == nil || len(header.Vote) == 0 { + logger.Warn("Missing header found", "num", blockNum) continue } From c1db58b321dac2b52329851163c97d8fef70e13a Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Mon, 16 Dec 2024 17:56:22 +0900 Subject: [PATCH 04/12] Fix lowest vote scanned epoch idx --- kaiax/gov/headergov/README.md | 4 ++-- kaiax/gov/headergov/impl/consensus.go | 14 +++++++------- kaiax/gov/headergov/impl/error.go | 2 +- kaiax/gov/headergov/impl/init.go | 24 ++++++++++++------------ kaiax/gov/headergov/impl/init_test.go | 4 ++-- kaiax/gov/headergov/impl/schema.go | 14 +++++++------- node/cn/api_backend_test.go | 2 +- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/kaiax/gov/headergov/README.md b/kaiax/gov/headergov/README.md index f6512770a..1bab82b35 100644 --- a/kaiax/gov/headergov/README.md +++ b/kaiax/gov/headergov/README.md @@ -94,9 +94,9 @@ num | effective parameter set at num "governanceDataBlockNums" => JSON.Marshal([num1, num2, ...]) ``` -- `lowestVoteScannedBlockNumKey`: The lowest block number whose vote data is scanned. That is, only vote block numbers which are greater than or equal to this value are stored in `governanceVoteDataBlockNums`. Grows downwards by `epoch` blocks. +- `lowestVoteScannedEpochIdx`: The lowest epoch index whose vote data is scanned. That is, only vote block numbers which are greater than or equal to this value are stored in `governanceVoteDataBlockNums`. Grows downwards by `epoch` blocks. ``` - "governanceLowestVoteScannedBlockNum" => Uint64BE(num) + "governanceLowestVoteScannedEpochIdx" => Uint64BE(num) ``` - `legacyIdxHistoryKey`: legacy governance data block numbers. diff --git a/kaiax/gov/headergov/impl/consensus.go b/kaiax/gov/headergov/impl/consensus.go index 605500183..eac06e9a6 100644 --- a/kaiax/gov/headergov/impl/consensus.go +++ b/kaiax/gov/headergov/impl/consensus.go @@ -230,14 +230,14 @@ func (h *headerGovModule) getExpectedGovernance(blockNum uint64) headergov.GovDa } func (h *headerGovModule) getVotesInEpoch(epochIdx uint64) map[uint64]headergov.VoteData { - lowestVoteScannedBlockNumPtr := ReadLowestVoteScannedBlockNum(h.ChainKv) - if lowestVoteScannedBlockNumPtr == nil { - panic("lowest vote scanned block num must exist") + lowestVoteScannedEpochIdxPtr := ReadLowestVoteScannedEpochIdx(h.ChainKv) + if lowestVoteScannedEpochIdxPtr == nil { + panic("lowest vote scanned epoch index must exist") } - lowestVoteScannedBlockNum := *lowestVoteScannedBlockNumPtr + lowestVoteScannedEpochIdx := *lowestVoteScannedEpochIdxPtr - if lowestVoteScannedBlockNum <= calcEpochStartBlock(epochIdx, h.epoch) { - logger.Info("scanning votes fastpath") + if lowestVoteScannedEpochIdx <= epochIdx { + logger.Debug("Scanning votes fastpath") votes := make(map[uint64]headergov.VoteData) h.mu.RLock() @@ -247,7 +247,7 @@ func (h *headerGovModule) getVotesInEpoch(epochIdx uint64) map[uint64]headergov. } return votes } else { - logger.Info("scanning votes slowpath") + logger.Debug("Scanning votes slowpath") return h.scanAllVotesInEpoch(epochIdx) } } diff --git a/kaiax/gov/headergov/impl/error.go b/kaiax/gov/headergov/impl/error.go index 0b3efcdba..8b41546b3 100644 --- a/kaiax/gov/headergov/impl/error.go +++ b/kaiax/gov/headergov/impl/error.go @@ -7,7 +7,7 @@ import ( var ( ErrZeroEpoch = errors.New("epoch cannot be zero") - ErrLowestVoteScannedBlockNotFound = errors.New("lowest vote scanned block not found") + ErrLowestVoteScannedEpochIdxFound = errors.New("lowest vote scanned epoch index not found") ErrVotePermissionDenied = errors.New("you don't have the right to vote") ErrInvalidKeyValue = errors.New("your vote couldn't be placed. Please check your vote's key and value") diff --git a/kaiax/gov/headergov/impl/init.go b/kaiax/gov/headergov/impl/init.go index ca660a2d2..df00ced25 100644 --- a/kaiax/gov/headergov/impl/init.go +++ b/kaiax/gov/headergov/impl/init.go @@ -98,8 +98,8 @@ func (h *headerGovModule) Init(opts *InitOpts) error { } // 2. Init votes. If votes exist in the latest epoch, read from DB. Otherwise, accumulate. - lowestVoteScannedBlockNumPtr := ReadLowestVoteScannedBlockNum(h.ChainKv) - if lowestVoteScannedBlockNumPtr != nil { + lowestVoteScannedEpochIdxPtr := ReadLowestVoteScannedEpochIdx(h.ChainKv) + if lowestVoteScannedEpochIdxPtr != nil { votes := readVoteDataFromDB(h.Chain, h.ChainKv) for blockNum, vote := range votes { @@ -116,13 +116,13 @@ func (h *headerGovModule) Init(opts *InitOpts) error { func (h *headerGovModule) Start() error { logger.Info("HeaderGovModule started") - lowestVoteScannedBlockNumPtr := ReadLowestVoteScannedBlockNum(h.ChainKv) - if lowestVoteScannedBlockNumPtr == nil { - return ErrLowestVoteScannedBlockNotFound + lowestVoteScannedEpochIdxPtr := ReadLowestVoteScannedEpochIdx(h.ChainKv) + if lowestVoteScannedEpochIdxPtr == nil { + return ErrLowestVoteScannedEpochIdxFound } // Scan all epochs in the background including 0th epoch - epochIdxIter := calcEpochIdx(*lowestVoteScannedBlockNumPtr, h.epoch) + epochIdxIter := *lowestVoteScannedEpochIdxPtr go func() { for int64(epochIdxIter) > 0 { epochIdxIter -= 1 @@ -182,13 +182,13 @@ func (h *headerGovModule) scanAllVotesInEpoch(epochIdx uint64) map[uint64]header } // accumulateVotesInEpoch scans and saves votes to cache and DB. -// Because this function updates lowestVoteScannedBlockNum, it verifies epochIdx. +// Because this function updates lowestVoteScannedEpochIdx, it verifies epochIdx. func (h *headerGovModule) accumulateVotesInEpoch(epochIdx uint64) { - lowestVoteScannedBlockNumPtr := ReadLowestVoteScannedBlockNum(h.ChainKv) + lowestVoteScannedEpochIdxPtr := ReadLowestVoteScannedEpochIdx(h.ChainKv) - // assert epochIdx == lowestVoteScannedBlockNum - 1 - if lowestVoteScannedBlockNumPtr != nil && *lowestVoteScannedBlockNumPtr != epochIdx+1 { - logger.Error("Invalid epochIdx", "epochIdx", epochIdx, "lowestScanned", *lowestVoteScannedBlockNumPtr) + // assert epochIdx == lowestVoteScannedEpochIdx - 1 + if lowestVoteScannedEpochIdxPtr != nil && *lowestVoteScannedEpochIdxPtr != epochIdx+1 { + logger.Error("Invalid epochIdx", "epochIdx", epochIdx, "lowestScanned", *lowestVoteScannedEpochIdxPtr) return } @@ -198,7 +198,7 @@ func (h *headerGovModule) accumulateVotesInEpoch(epochIdx uint64) { InsertVoteDataBlockNum(h.ChainKv, blockNum) } - WriteLowestVoteScannedBlockNum(h.ChainKv, epochIdx) + WriteLowestVoteScannedEpochIdx(h.ChainKv, epochIdx) logger.Info("Accumulated votes", "epochIdx", epochIdx, "lowestScanned", epochIdx) } diff --git a/kaiax/gov/headergov/impl/init_test.go b/kaiax/gov/headergov/impl/init_test.go index c0891a90d..69652dc48 100644 --- a/kaiax/gov/headergov/impl/init_test.go +++ b/kaiax/gov/headergov/impl/init_test.go @@ -69,7 +69,7 @@ func newHeaderGovModule(t *testing.T, config *params.ChainConfig) *headerGovModu ChainConfig: config, }) require.NoError(t, err) - WriteLowestVoteScannedBlockNum(db, 0) + WriteLowestVoteScannedEpochIdx(db, 0) h.Start() return h @@ -132,7 +132,7 @@ func TestInitialDB(t *testing.T) { assert.Nil(t, ReadLegacyIdxHistory(h.ChainKv)) assert.Equal(t, StoredUint64Array{0}, ReadGovDataBlockNums(h.ChainKv)) assert.Nil(t, StoredUint64Array(nil), ReadVoteDataBlockNums(h.ChainKv)) - assert.Equal(t, uint64(0), *ReadLowestVoteScannedBlockNum(h.ChainKv)) + assert.Equal(t, uint64(0), *ReadLowestVoteScannedEpochIdx(h.ChainKv)) } func TestGetGenesisParamNames(t *testing.T) { diff --git a/kaiax/gov/headergov/impl/schema.go b/kaiax/gov/headergov/impl/schema.go index 0cb1b83b1..866934e2a 100644 --- a/kaiax/gov/headergov/impl/schema.go +++ b/kaiax/gov/headergov/impl/schema.go @@ -12,7 +12,7 @@ import ( var ( voteDataBlockNumsKey = []byte("governanceVoteDataBlockNums") govDataBlockNumsKey = []byte("governanceDataBlockNums") - lowestVoteScannedBlockNumKey = []byte("governanceLowestVoteScannedBlockNum") // grows downwards + lowestVoteScannedEpochIdxKey = []byte("governanceLowestVoteScannedEpochIdx") // grows downwards legacyIdxHistoryKey = []byte("governanceIdxHistory") mu = &sync.RWMutex{} @@ -100,17 +100,17 @@ func WriteGovDataBlockNums(db database.Database, govDataBlockNums StoredUint64Ar writeStoredUint64Array(db, govDataBlockNumsKey, govDataBlockNums) } -func ReadLowestVoteScannedBlockNum(db database.Database) *uint64 { +func ReadLowestVoteScannedEpochIdx(db database.Database) *uint64 { mu.RLock() defer mu.RUnlock() - b, err := db.Get(lowestVoteScannedBlockNumKey) + b, err := db.Get(lowestVoteScannedEpochIdxKey) if err != nil || len(b) == 0 { return nil } if len(b) != 8 { - logger.Error("Invalid lowestVoteScannedBlockNum data length", "length", len(b)) + logger.Error("Invalid lowestVoteScannedEpochIdx data length", "length", len(b)) return nil } @@ -118,13 +118,13 @@ func ReadLowestVoteScannedBlockNum(db database.Database) *uint64 { return &ret } -func WriteLowestVoteScannedBlockNum(db database.Database, lowestVoteScannedBlockNum uint64) { +func WriteLowestVoteScannedEpochIdx(db database.Database, lowestVoteScannedEpochIdx uint64) { mu.Lock() defer mu.Unlock() b := make([]byte, 8) - binary.BigEndian.PutUint64(b, lowestVoteScannedBlockNum) - db.Put(lowestVoteScannedBlockNumKey, b) + binary.BigEndian.PutUint64(b, lowestVoteScannedEpochIdx) + db.Put(lowestVoteScannedEpochIdxKey, b) } func ReadLegacyIdxHistory(db database.Database) StoredUint64Array { diff --git a/node/cn/api_backend_test.go b/node/cn/api_backend_test.go index c38eba7cc..4b886dfc2 100644 --- a/node/cn/api_backend_test.go +++ b/node/cn/api_backend_test.go @@ -181,7 +181,7 @@ func testGovModule(chain gov_impl.BlockChain) *gov_impl.GovModule { config.Governance = params.GetDefaultGovernanceConfig() config.Istanbul = params.GetDefaultIstanbulConfig() // chain can be a mock, this prevents reading all headers in an epoch. - headergov_impl.WriteLowestVoteScannedBlockNum(db.GetMiscDB(), 0) + headergov_impl.WriteLowestVoteScannedEpochIdx(db.GetMiscDB(), 0) govModule := gov_impl.NewGovModule() govModule.Init(&gov_impl.InitOpts{ ChainConfig: config, From 2cc26442286ac09a93b67eddfce0f1c29a0cc78d Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Mon, 16 Dec 2024 19:50:48 +0900 Subject: [PATCH 05/12] Adopt valset module style --- kaiax/gov/headergov/impl/consensus.go | 8 +- kaiax/gov/headergov/impl/execution.go | 18 ++-- kaiax/gov/headergov/impl/execution_test.go | 2 +- kaiax/gov/headergov/impl/init.go | 98 +++++++++++++--------- kaiax/gov/headergov/impl/schema.go | 32 ++----- 5 files changed, 82 insertions(+), 76 deletions(-) diff --git a/kaiax/gov/headergov/impl/consensus.go b/kaiax/gov/headergov/impl/consensus.go index eac06e9a6..5696e2ec6 100644 --- a/kaiax/gov/headergov/impl/consensus.go +++ b/kaiax/gov/headergov/impl/consensus.go @@ -230,13 +230,13 @@ func (h *headerGovModule) getExpectedGovernance(blockNum uint64) headergov.GovDa } func (h *headerGovModule) getVotesInEpoch(epochIdx uint64) map[uint64]headergov.VoteData { - lowestVoteScannedEpochIdxPtr := ReadLowestVoteScannedEpochIdx(h.ChainKv) - if lowestVoteScannedEpochIdxPtr == nil { + pBorder := ReadLowestVoteScannedEpochIdx(h.ChainKv) + if pBorder == nil { panic("lowest vote scanned epoch index must exist") } - lowestVoteScannedEpochIdx := *lowestVoteScannedEpochIdxPtr + border := *pBorder - if lowestVoteScannedEpochIdx <= epochIdx { + if border <= epochIdx { logger.Debug("Scanning votes fastpath") votes := make(map[uint64]headergov.VoteData) diff --git a/kaiax/gov/headergov/impl/execution.go b/kaiax/gov/headergov/impl/execution.go index b77737e72..0736899f1 100644 --- a/kaiax/gov/headergov/impl/execution.go +++ b/kaiax/gov/headergov/impl/execution.go @@ -44,16 +44,14 @@ func (h *headerGovModule) PostInsertBlock(b *types.Block) error { func (h *headerGovModule) HandleVote(blockNum uint64, vote headergov.VoteData) error { // if governance vote (i.e., not validator vote), add to vote if _, ok := gov.Params[vote.Name()]; ok { - h.AddVote(calcEpochIdx(blockNum, h.epoch), blockNum, vote) + h.AddVote(blockNum, vote) InsertVoteDataBlockNum(h.ChainKv, blockNum) } // if the vote was mine, remove it. for i, myvote := range h.myVotes { - if bytes.Equal(myvote.Voter().Bytes(), vote.Voter().Bytes()) && - myvote.Name() == vote.Name() && - reflect.DeepEqual(myvote.Value(), vote.Value()) { - logger.Debug("Removing myvote", "vote", h.myVotes[i]) + if isEqualVotes(myvote, vote) { + logger.Debug("Removing myvote", "vote", myvote) h.PopMyVotes(i) break } @@ -78,12 +76,20 @@ func (h *headerGovModule) AddGov(blockNum uint64, gov headergov.GovData) { h.history = headergov.GovsToHistory(h.governances) } -func (h *headerGovModule) AddVote(epochIdx, blockNum uint64, vote headergov.VoteData) { +func (h *headerGovModule) AddVote(blockNum uint64, vote headergov.VoteData) { h.mu.Lock() defer h.mu.Unlock() + epochIdx := calcEpochIdx(blockNum, h.epoch) + if _, ok := h.groupedVotes[epochIdx]; !ok { h.groupedVotes[epochIdx] = make(headergov.VotesInEpoch) } h.groupedVotes[epochIdx][blockNum] = vote } + +func isEqualVotes(a headergov.VoteData, b headergov.VoteData) bool { + return bytes.Equal(a.Voter().Bytes(), b.Voter().Bytes()) && + a.Name() == b.Name() && + reflect.DeepEqual(a.Value(), b.Value()) +} diff --git a/kaiax/gov/headergov/impl/execution_test.go b/kaiax/gov/headergov/impl/execution_test.go index a5d8e1269..117d856a7 100644 --- a/kaiax/gov/headergov/impl/execution_test.go +++ b/kaiax/gov/headergov/impl/execution_test.go @@ -81,7 +81,7 @@ func TestVote(t *testing.T) { ) for i := 0; i < n; i++ { - h.AddVote(calcEpochIdx(uint64(i), uint64(epoch)), uint64(i), v) + h.AddVote(uint64(i), v) } assert.Equal(t, n, len(h.VoteBlockNums())) diff --git a/kaiax/gov/headergov/impl/init.go b/kaiax/gov/headergov/impl/init.go index df00ced25..9802e2e52 100644 --- a/kaiax/gov/headergov/impl/init.go +++ b/kaiax/gov/headergov/impl/init.go @@ -3,6 +3,7 @@ package impl import ( "math/big" "sync" + "sync/atomic" "github.com/kaiachain/kaia/blockchain/state" "github.com/kaiachain/kaia/blockchain/types" @@ -56,6 +57,9 @@ type headerGovModule struct { // for APIs nodeAddress common.Address myVotes []headergov.VoteData // queue + + quit atomic.Int32 // stop the migration thread + wg sync.WaitGroup } func NewHeaderGovModule() *headerGovModule { @@ -72,69 +76,87 @@ func (h *headerGovModule) Init(opts *InitOpts) error { h.Chain = opts.Chain h.ValSet = opts.ValSet h.nodeAddress = opts.NodeAddress - h.myVotes = make([]headergov.VoteData, 0) - h.mu = &sync.RWMutex{} h.epoch = h.ChainConfig.Istanbul.Epoch if h.epoch == 0 { return ErrZeroEpoch } - // 1. Init gov. If Gov DB is empty, migrate from legacy governance DB. - if ReadGovDataBlockNums(h.ChainKv) == nil { - legacyGovBlockNums := ReadLegacyIdxHistory(h.ChainKv) - if legacyGovBlockNums == nil { - legacyGovBlockNums = StoredUint64Array{0} - } - WriteGovDataBlockNums(h.ChainKv, legacyGovBlockNums) - } + h.initSchema() + // init memory h.groupedVotes = make(map[uint64]headergov.VotesInEpoch) h.governances = make(map[uint64]headergov.GovData) - govs := readGovDataFromDB(h.Chain, h.ChainKv) h.history = make(headergov.History) + h.myVotes = make([]headergov.VoteData, 0) + h.mu = &sync.RWMutex{} + + govs := readGovDataFromDB(h.Chain, h.ChainKv) for blockNum, gov := range govs { h.AddGov(blockNum, gov) } - // 2. Init votes. If votes exist in the latest epoch, read from DB. Otherwise, accumulate. - lowestVoteScannedEpochIdxPtr := ReadLowestVoteScannedEpochIdx(h.ChainKv) - if lowestVoteScannedEpochIdxPtr != nil { - votes := readVoteDataFromDB(h.Chain, h.ChainKv) + votes := readVoteDataFromDB(h.Chain, h.ChainKv) + for blockNum, vote := range votes { + h.AddVote(blockNum, vote) + } - for blockNum, vote := range votes { - h.AddVote(calcEpochIdx(blockNum, h.epoch), blockNum, vote) + return nil +} + +func (h *headerGovModule) initSchema() { + // 1. Init gov from legacy governance DB, if empty. + if ReadGovDataBlockNums(h.ChainKv) == nil { + legacyGovBlockNums := ReadLegacyIdxHistory(h.ChainKv) + if legacyGovBlockNums == nil { + legacyGovBlockNums = StoredUint64Array{0} } - } else { + WriteGovDataBlockNums(h.ChainKv, legacyGovBlockNums) + } + + // 2. Init vote and lowest vote scanned epoch index, if empty. + if ReadLowestVoteScannedEpochIdx(h.ChainKv) == nil { latestEpochIdx := calcEpochIdx(h.Chain.CurrentBlock().NumberU64(), h.epoch) h.accumulateVotesInEpoch(latestEpochIdx) } - - return nil } func (h *headerGovModule) Start() error { logger.Info("HeaderGovModule started") - lowestVoteScannedEpochIdxPtr := ReadLowestVoteScannedEpochIdx(h.ChainKv) - if lowestVoteScannedEpochIdxPtr == nil { - return ErrLowestVoteScannedEpochIdxFound - } - - // Scan all epochs in the background including 0th epoch - epochIdxIter := *lowestVoteScannedEpochIdxPtr - go func() { - for int64(epochIdxIter) > 0 { - epochIdxIter -= 1 - h.accumulateVotesInEpoch(epochIdxIter) - } - }() + // Reset the quit state. + h.quit.Store(0) + h.wg.Add(1) + go h.migrate() return nil } func (h *headerGovModule) Stop() { logger.Info("HeaderGovModule stopped") + h.quit.Store(1) + h.wg.Wait() +} + +func (h *headerGovModule) migrate() { + defer h.wg.Done() + + // Scan all epochs in the background including 0th epoch + pBorder := ReadLowestVoteScannedEpochIdx(h.ChainKv) + if pBorder == nil { + logger.Crit("Unexpected nil: lowest vote scanned epoch index") + return + } + + border := *pBorder + for int64(border) > 0 { + if h.quit.Load() == 1 { + return + } + + border -= 1 + h.accumulateVotesInEpoch(border) + } } func (h *headerGovModule) isKoreHF(num uint64) bool { @@ -184,17 +206,15 @@ func (h *headerGovModule) scanAllVotesInEpoch(epochIdx uint64) map[uint64]header // accumulateVotesInEpoch scans and saves votes to cache and DB. // Because this function updates lowestVoteScannedEpochIdx, it verifies epochIdx. func (h *headerGovModule) accumulateVotesInEpoch(epochIdx uint64) { - lowestVoteScannedEpochIdxPtr := ReadLowestVoteScannedEpochIdx(h.ChainKv) - - // assert epochIdx == lowestVoteScannedEpochIdx - 1 - if lowestVoteScannedEpochIdxPtr != nil && *lowestVoteScannedEpochIdxPtr != epochIdx+1 { - logger.Error("Invalid epochIdx", "epochIdx", epochIdx, "lowestScanned", *lowestVoteScannedEpochIdxPtr) + pBorder := ReadLowestVoteScannedEpochIdx(h.ChainKv) + if pBorder != nil && *pBorder != epochIdx+1 { + logger.Error("Invalid epochIdx", "epochIdx", epochIdx, "lowestScanned", *pBorder) return } votes := h.scanAllVotesInEpoch(epochIdx) for blockNum, vote := range votes { - h.AddVote(epochIdx, blockNum, vote) + h.AddVote(blockNum, vote) InsertVoteDataBlockNum(h.ChainKv, blockNum) } diff --git a/kaiax/gov/headergov/impl/schema.go b/kaiax/gov/headergov/impl/schema.go index 866934e2a..2a0bf167e 100644 --- a/kaiax/gov/headergov/impl/schema.go +++ b/kaiax/gov/headergov/impl/schema.go @@ -20,8 +20,8 @@ var ( type StoredUint64Array []uint64 -// readStoredUint64ArrayNoLock should be called only when the caller holds the lock. -func readStoredUint64ArrayNoLock(db database.Database, key []byte) StoredUint64Array { +// readStoredUint64Array should be called only when the caller holds the lock. +func readStoredUint64Array(db database.Database, key []byte) StoredUint64Array { b, err := db.Get(key) if err != nil || len(b) == 0 { return nil @@ -35,8 +35,8 @@ func readStoredUint64ArrayNoLock(db database.Database, key []byte) StoredUint64A return ret } -// writeStoredUint64ArrayNoLock should be called only when the caller holds the lock. -func writeStoredUint64ArrayNoLock(db database.Database, key []byte, data StoredUint64Array) { +// writeStoredUint64Array should be called only when the caller holds the lock. +func writeStoredUint64Array(db database.Database, key []byte, data StoredUint64Array) { b, err := json.Marshal(data) if err != nil { logger.Error("Failed to marshal voteDataBlocks", "err", err) @@ -48,20 +48,6 @@ func writeStoredUint64ArrayNoLock(db database.Database, key []byte, data StoredU } } -func readStoredUint64Array(db database.Database, key []byte) StoredUint64Array { - mu.RLock() - defer mu.RUnlock() - - return readStoredUint64ArrayNoLock(db, key) -} - -func writeStoredUint64Array(db database.Database, key []byte, data StoredUint64Array) { - mu.Lock() - defer mu.Unlock() - - writeStoredUint64ArrayNoLock(db, key, data) -} - func ReadVoteDataBlockNums(db database.Database) StoredUint64Array { return readStoredUint64Array(db, voteDataBlockNumsKey) } @@ -74,7 +60,7 @@ func InsertVoteDataBlockNum(db database.Database, blockNum uint64) { mu.Lock() defer mu.Unlock() - blockNums := readStoredUint64ArrayNoLock(db, voteDataBlockNumsKey) + blockNums := readStoredUint64Array(db, voteDataBlockNumsKey) if blockNums == nil { blockNums = StoredUint64Array{} } @@ -89,7 +75,7 @@ func InsertVoteDataBlockNum(db database.Database, blockNum uint64) { blockNums = append(blockNums, blockNum) slices.Sort(blockNums) - writeStoredUint64ArrayNoLock(db, voteDataBlockNumsKey, blockNums) + writeStoredUint64Array(db, voteDataBlockNumsKey, blockNums) } func ReadGovDataBlockNums(db database.Database) StoredUint64Array { @@ -101,9 +87,6 @@ func WriteGovDataBlockNums(db database.Database, govDataBlockNums StoredUint64Ar } func ReadLowestVoteScannedEpochIdx(db database.Database) *uint64 { - mu.RLock() - defer mu.RUnlock() - b, err := db.Get(lowestVoteScannedEpochIdxKey) if err != nil || len(b) == 0 { return nil @@ -119,9 +102,6 @@ func ReadLowestVoteScannedEpochIdx(db database.Database) *uint64 { } func WriteLowestVoteScannedEpochIdx(db database.Database, lowestVoteScannedEpochIdx uint64) { - mu.Lock() - defer mu.Unlock() - b := make([]byte, 8) binary.BigEndian.PutUint64(b, lowestVoteScannedEpochIdx) db.Put(lowestVoteScannedEpochIdxKey, b) From f5c4543311650699dfd0c67fa9b88fb704ec45dd Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Tue, 17 Dec 2024 14:29:13 +0900 Subject: [PATCH 06/12] Use getChainConfig for headergov tests --- kaiax/gov/headergov/impl/api_test.go | 12 +-- kaiax/gov/headergov/impl/consensus_test.go | 48 +++++------- kaiax/gov/headergov/impl/execution_test.go | 44 ++++++----- kaiax/gov/headergov/impl/getter_test.go | 90 ++++++++++------------ kaiax/gov/headergov/impl/init.go | 3 +- kaiax/gov/headergov/impl/init_test.go | 14 +++- 6 files changed, 100 insertions(+), 111 deletions(-) diff --git a/kaiax/gov/headergov/impl/api_test.go b/kaiax/gov/headergov/impl/api_test.go index 2cb89d3bd..09ab4a0b8 100644 --- a/kaiax/gov/headergov/impl/api_test.go +++ b/kaiax/gov/headergov/impl/api_test.go @@ -4,27 +4,23 @@ import ( "fmt" "testing" - "github.com/kaiachain/kaia/params" "github.com/stretchr/testify/assert" ) func newHeaderGovAPI(t *testing.T) *headerGovAPI { - h := newHeaderGovModule(t, ¶ms.ChainConfig{ - Istanbul: ¶ms.IstanbulConfig{ - Epoch: 1000, - }, - }) + chainConfig := getTestChainConfig() + h := newHeaderGovModule(t, chainConfig) return NewHeaderGovAPI(h) } -func TestUpperBoundBaseFeeSet(t *testing.T) { +func TestVoteUpperBoundBaseFee(t *testing.T) { api := newHeaderGovAPI(t) s, err := api.Vote("kip71.upperboundbasefee", uint64(1)) assert.Equal(t, ErrUpperBoundBaseFee, err) assert.Equal(t, "", s) } -func TestLowerBoundBaseFeeSet(t *testing.T) { +func TestVoteLowerBoundBaseFee(t *testing.T) { api := newHeaderGovAPI(t) s, err := api.Vote("kip71.lowerboundbasefee", uint64(1e18)) assert.Equal(t, ErrLowerBoundBaseFee, err) diff --git a/kaiax/gov/headergov/impl/consensus_test.go b/kaiax/gov/headergov/impl/consensus_test.go index cadcc215c..e0817024d 100644 --- a/kaiax/gov/headergov/impl/consensus_test.go +++ b/kaiax/gov/headergov/impl/consensus_test.go @@ -9,7 +9,6 @@ import ( "github.com/kaiachain/kaia/kaiax/gov" "github.com/kaiachain/kaia/kaiax/gov/headergov" "github.com/kaiachain/kaia/log" - "github.com/kaiachain/kaia/params" "github.com/stretchr/testify/assert" ) @@ -20,7 +19,7 @@ func TestVerifyHeader(t *testing.T) { voteBytes, _ = headergov.NewVoteData(common.Address{1}, string(gov.GovernanceUnitPrice), uint64(100)).ToVoteBytes() govBytes, _ = headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: uint64(100)}).ToGovBytes() invalidGovBytes, _ = headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: uint64(200)}).ToGovBytes() - h = newHeaderGovModule(t, ¶ms.ChainConfig{Istanbul: ¶ms.IstanbulConfig{Epoch: 1000}}) + h = newHeaderGovModule(t, getTestChainConfig()) invalidVoteRlp = common.FromHex("0xea9452d41ca72af615a1ac3301b0a93efa222ecc7541947265776172642e6d696e74696e67616d6f756e74") ) @@ -34,13 +33,13 @@ func TestVerifyHeader(t *testing.T) { {desc: "valid vote", header: &types.Header{Number: big.NewInt(1), Vote: voteBytes, Extra: extra}, expectedError: nil}, {desc: "invalid vote rlp", header: &types.Header{Number: big.NewInt(1), Vote: []byte{1, 2, 3}, Extra: extra}, expectedError: headergov.ErrInvalidRlp}, {desc: "invalid vote bytes", header: &types.Header{Number: big.NewInt(1), Vote: invalidVoteRlp, Extra: extra}, expectedError: headergov.ErrInvalidRlp}, - {desc: "valid gov", header: &types.Header{Number: big.NewInt(1000), Governance: govBytes, Extra: extra}, expectedError: nil}, - {desc: "invalid gov rlp", header: &types.Header{Number: big.NewInt(1000), Governance: []byte{1, 2, 3}, Extra: extra}, expectedError: headergov.ErrInvalidRlp}, - {desc: "gov must not be nil", header: &types.Header{Number: big.NewInt(1000), Governance: nil}, expectedError: ErrGovVerification}, - {desc: "gov mismatch", header: &types.Header{Number: big.NewInt(1000), Governance: invalidGovBytes}, expectedError: ErrGovVerification}, - {desc: "gov not on epoch", header: &types.Header{Number: big.NewInt(1001), Governance: []byte{1, 2, 3}}, expectedError: ErrGovInNonEpochBlock}, - {desc: "gov must be nil", header: &types.Header{Number: big.NewInt(2000), Governance: govBytes}, expectedError: ErrGovVerification}, - {desc: "valid gov", header: &types.Header{Number: big.NewInt(2000), Governance: nil}, expectedError: nil}, + {desc: "valid gov", header: &types.Header{Number: big.NewInt(100), Governance: govBytes, Extra: extra}, expectedError: nil}, + {desc: "invalid gov rlp", header: &types.Header{Number: big.NewInt(100), Governance: []byte{1, 2, 3}, Extra: extra}, expectedError: headergov.ErrInvalidRlp}, + {desc: "gov must not be nil", header: &types.Header{Number: big.NewInt(100), Governance: nil}, expectedError: ErrGovVerification}, + {desc: "gov mismatch", header: &types.Header{Number: big.NewInt(100), Governance: invalidGovBytes}, expectedError: ErrGovVerification}, + {desc: "gov not on epoch", header: &types.Header{Number: big.NewInt(101), Governance: []byte{1, 2, 3}}, expectedError: ErrGovInNonEpochBlock}, + {desc: "gov must be nil", header: &types.Header{Number: big.NewInt(200), Governance: govBytes}, expectedError: ErrGovVerification}, + {desc: "valid gov", header: &types.Header{Number: big.NewInt(200), Governance: nil}, expectedError: nil}, } for _, tc := range tcs { @@ -54,11 +53,7 @@ func TestVerifyHeader(t *testing.T) { func TestVerifyVote(t *testing.T) { var ( - h = newHeaderGovModule(t, ¶ms.ChainConfig{ - Istanbul: ¶ms.IstanbulConfig{ - Epoch: 1000, - }, - }) + h = newHeaderGovModule(t, getTestChainConfig()) statedb, _ = h.Chain.State() eoa = common.HexToAddress("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266") @@ -93,47 +88,42 @@ func TestVerifyVote(t *testing.T) { } func TestGetVotesInEpoch(t *testing.T) { - h := newHeaderGovModule(t, ¶ms.ChainConfig{ - Istanbul: ¶ms.IstanbulConfig{ - Epoch: 1000, - }, - }) + h := newHeaderGovModule(t, getTestChainConfig()) paramName := string(gov.GovernanceUnitPrice) v1 := headergov.NewVoteData(common.Address{1}, paramName, uint64(100)) - h.HandleVote(500, v1) + h.HandleVote(50, v1) v2 := headergov.NewVoteData(common.Address{2}, paramName, uint64(200)) - h.HandleVote(1500, v2) + h.HandleVote(150, v2) - assert.Equal(t, map[uint64]headergov.VoteData{500: v1}, h.getVotesInEpoch(0)) - assert.Equal(t, map[uint64]headergov.VoteData{1500: v2}, h.getVotesInEpoch(1)) + assert.Equal(t, map[uint64]headergov.VoteData{50: v1}, h.getVotesInEpoch(0)) + assert.Equal(t, map[uint64]headergov.VoteData{150: v2}, h.getVotesInEpoch(1)) } func TestGetExpectedGovernance(t *testing.T) { log.EnableLogForTest(log.LvlCrit, log.LvlError) var ( paramName = string(gov.GovernanceUnitPrice) - config = ¶ms.ChainConfig{Istanbul: ¶ms.IstanbulConfig{Epoch: 1000}} - h = newHeaderGovModule(t, config) + h = newHeaderGovModule(t, getTestChainConfig()) v1 = headergov.NewVoteData(common.Address{1}, paramName, uint64(100)) v2 = headergov.NewVoteData(common.Address{2}, paramName, uint64(200)) g = headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: uint64(200)}) ) // v2 overrides v1 - h.HandleVote(500, v1) - h.HandleVote(600, v2) + h.HandleVote(50, v1) + h.HandleVote(60, v2) // test many times for deterministic result for range 100 { - assert.Equal(t, g, h.getExpectedGovernance(1000)) + assert.Equal(t, g, h.getExpectedGovernance(100)) } } func TestPrepareHeader(t *testing.T) { log.EnableLogForTest(log.LvlCrit, log.LvlCrit) var ( - h = newHeaderGovModule(t, ¶ms.ChainConfig{Istanbul: ¶ms.IstanbulConfig{Epoch: 1000}}) + h = newHeaderGovModule(t, getTestChainConfig()) vote = headergov.NewVoteData(h.nodeAddress, string(gov.GovernanceUnitPrice), uint64(100)) header = &types.Header{} ) diff --git a/kaiax/gov/headergov/impl/execution_test.go b/kaiax/gov/headergov/impl/execution_test.go index 117d856a7..2b9f61c68 100644 --- a/kaiax/gov/headergov/impl/execution_test.go +++ b/kaiax/gov/headergov/impl/execution_test.go @@ -8,24 +8,23 @@ import ( "github.com/kaiachain/kaia/common" "github.com/kaiachain/kaia/kaiax/gov" "github.com/kaiachain/kaia/kaiax/gov/headergov" - "github.com/kaiachain/kaia/params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestPostInsertBlock(t *testing.T) { - h := newHeaderGovModule(t, ¶ms.ChainConfig{Istanbul: ¶ms.IstanbulConfig{Epoch: 10}}) + h := newHeaderGovModule(t, getTestChainConfig()) vote, _ := headergov.NewVoteData(common.Address{1}, string(gov.GovernanceUnitPrice), uint64(100)).ToVoteBytes() gov, _ := headergov.NewGovData(gov.PartialParamSet{ gov.GovernanceUnitPrice: uint64(100), }).ToGovBytes() voteBlock := types.NewBlockWithHeader(&types.Header{ - Number: big.NewInt(5), + Number: big.NewInt(50), Vote: vote, }) govBlock := types.NewBlockWithHeader(&types.Header{ - Number: big.NewInt(10), + Number: big.NewInt(100), Governance: gov, }) @@ -39,21 +38,21 @@ func TestPostInsertBlock(t *testing.T) { err = h.PostInsertBlock(govBlock) assert.NoError(t, err) assert.Equal(t, 2, len(h.governances)) + + // PostInsertBlock does not validate the block, so non-epoch block with gov is also accepted + govBlock.Header().Number = big.NewInt(123) + err = h.PostInsertBlock(govBlock) + assert.NoError(t, err) } func TestHandleVoteGov(t *testing.T) { - h := newHeaderGovModule(t, ¶ms.ChainConfig{ - Istanbul: ¶ms.IstanbulConfig{ - Epoch: 10, - }, - }) - + h := newHeaderGovModule(t, getTestChainConfig()) v := headergov.NewVoteData(common.Address{1}, string(gov.GovernanceUnitPrice), uint64(100)) require.NotNil(t, v) require.Equal(t, 0, len(h.groupedVotes)) require.Equal(t, 1, len(h.governances)) // gov at genesis - voteBlock := uint64(5) - govBlock := uint64(10) + voteBlock := uint64(50) + govBlock := uint64(100) // test duplicate vote handling for range 2 { @@ -72,13 +71,14 @@ func TestHandleVoteGov(t *testing.T) { } } -func TestVote(t *testing.T) { +func TestAddVote(t *testing.T) { var ( - v = headergov.NewVoteData(common.HexToAddress("0x1"), string(gov.GovernanceUnitPrice), uint64(100)) - epoch = 3 - n = 10 - h = newHeaderGovModule(t, ¶ms.ChainConfig{Istanbul: ¶ms.IstanbulConfig{Epoch: uint64(epoch)}}) + v = headergov.NewVoteData(common.HexToAddress("0x1"), string(gov.GovernanceUnitPrice), uint64(100)) + n = 10 + config = getTestChainConfig() ) + config.Istanbul.Epoch = 3 + h := newHeaderGovModule(t, config) for i := 0; i < n; i++ { h.AddVote(uint64(i), v) @@ -88,12 +88,14 @@ func TestVote(t *testing.T) { assert.Equal(t, 4, len(h.groupedVotes)) // ceil(n/epoch) } -func TestGov(t *testing.T) { +func TestAddGov(t *testing.T) { var ( - g = headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: uint64(100)}) - n = 10 - h = newHeaderGovModule(t, ¶ms.ChainConfig{Istanbul: ¶ms.IstanbulConfig{Epoch: 1}}) + g = headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: uint64(100)}) + n = 10 + config = getTestChainConfig() ) + config.Istanbul.Epoch = 1 + h := newHeaderGovModule(t, config) for i := 0; i < n; i++ { h.AddGov(uint64(i), g) diff --git a/kaiax/gov/headergov/impl/getter_test.go b/kaiax/gov/headergov/impl/getter_test.go index 06b8800c2..0c6a067dd 100644 --- a/kaiax/gov/headergov/impl/getter_test.go +++ b/kaiax/gov/headergov/impl/getter_test.go @@ -8,15 +8,13 @@ import ( "github.com/kaiachain/kaia/kaiax/gov" "github.com/kaiachain/kaia/kaiax/gov/headergov" "github.com/kaiachain/kaia/log" - "github.com/kaiachain/kaia/params" "github.com/stretchr/testify/assert" ) func TestEffectiveParams(t *testing.T) { log.EnableLogForTest(log.LvlCrit, log.LvlDebug) - epoch := uint64(1000) gov := map[uint64]headergov.GovData{ - 1000: headergov.NewGovData(gov.PartialParamSet{ + 100: headergov.NewGovData(gov.PartialParamSet{ gov.GovernanceUnitPrice: uint64(750), }), } @@ -28,26 +26,23 @@ func TestEffectiveParams(t *testing.T) { expectedPrice uint64 }{ {"Pre-Kore, Block 0", 999999999, 0, 250e9}, - {"Pre-Kore, Block 1000", 999999999, 1000, 250e9}, - {"Pre-Kore, Block 1001", 999999999, 1001, 250e9}, - {"Pre-Kore, Block 2000", 999999999, 2000, 250e9}, - {"Pre-Kore, Block 2001", 999999999, 2001, 750}, + {"Pre-Kore, Block 100", 999999999, 100, 250e9}, + {"Pre-Kore, Block 101", 999999999, 101, 250e9}, + {"Pre-Kore, Block 200", 999999999, 200, 250e9}, + {"Pre-Kore, Block 201", 999999999, 201, 750}, {"Post-Kore, Block 0", 0, 0, 250e9}, - {"Post-Kore, Block 1000", 0, 1000, 250e9}, - {"Post-Kore, Block 1001", 0, 1001, 250e9}, - {"Post-Kore, Block 2000", 0, 2000, 750}, - {"Post-Kore, Block 2001", 0, 2001, 750}, + {"Post-Kore, Block 100", 0, 100, 250e9}, + {"Post-Kore, Block 101", 0, 101, 250e9}, + {"Post-Kore, Block 200", 0, 200, 750}, + {"Post-Kore, Block 201", 0, 201, 750}, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - config := ¶ms.ChainConfig{ - KoreCompatibleBlock: big.NewInt(int64(tc.koreBlock)), - Istanbul: ¶ms.IstanbulConfig{ - Epoch: epoch, - }, - } + config := getTestChainConfig() + config.KoreCompatibleBlock = big.NewInt(int64(tc.koreBlock)) + config.UnitPrice = 250e9 h := newHeaderGovModule(t, config) for num, g := range gov { h.HandleGov(num, g) @@ -60,27 +55,23 @@ func TestEffectiveParams(t *testing.T) { } func TestEffectiveParamsPartial(t *testing.T) { - var ( - epoch = uint64(1000) - h = newHeaderGovModule(t, ¶ms.ChainConfig{ - KoreCompatibleBlock: big.NewInt(0), - Istanbul: ¶ms.IstanbulConfig{Epoch: epoch}, - }) - ) + config := getTestChainConfig() + config.KoreCompatibleBlock = big.NewInt(0) + h := newHeaderGovModule(t, config) testCases := []struct { blockNum uint64 expectedPrice uint64 }{ {0, 0}, - {1000, 0}, - {2000, 1}, - {3000, 2}, - {4000, 3}, + {100, 0}, + {200, 1}, + {300, 2}, + {400, 3}, } for i, govPrice := range []uint64{0, 1, 2, 3} { - h.AddGov(uint64(i*1000), headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: govPrice})) + h.AddGov(uint64(i*100), headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: govPrice})) } for _, tc := range testCases { @@ -92,7 +83,6 @@ func TestEffectiveParamsPartial(t *testing.T) { } func TestPrevEpochStart(t *testing.T) { - epoch := uint64(1000) type TestCase struct { blockNum uint64 expectedGov uint64 @@ -100,40 +90,40 @@ func TestPrevEpochStart(t *testing.T) { preKoreTcs := []TestCase{ {0, 0}, - {999, 0}, - {1000, 0}, - {1001, 0}, - {1999, 0}, - {2000, 0}, - {2001, 1000}, - {2999, 1000}, - {3000, 1000}, - {3001, 2000}, + {99, 0}, + {100, 0}, + {101, 0}, + {199, 0}, + {200, 0}, + {201, 100}, + {299, 100}, + {300, 100}, + {301, 200}, } for _, tc := range preKoreTcs { t.Run(fmt.Sprintf("Pre-Kore Block %d", tc.blockNum), func(t *testing.T) { - result := PrevEpochStart(tc.blockNum, epoch, false) + result := PrevEpochStart(tc.blockNum, 100, false) assert.Equal(t, tc.expectedGov, result, "Incorrect governance data block for block %d", tc.blockNum) }) } postKoreTcs := []TestCase{ {0, 0}, - {999, 0}, - {1000, 0}, - {1001, 0}, - {1999, 0}, - {2000, 1000}, - {2001, 1000}, - {2999, 1000}, - {3000, 2000}, - {3001, 2000}, + {99, 0}, + {100, 0}, + {101, 0}, + {199, 0}, + {200, 100}, + {201, 100}, + {299, 100}, + {300, 200}, + {301, 200}, } for _, tc := range postKoreTcs { t.Run(fmt.Sprintf("Post-Kore Block %d", tc.blockNum), func(t *testing.T) { - result := PrevEpochStart(tc.blockNum, epoch, true) + result := PrevEpochStart(tc.blockNum, 100, true) assert.Equal(t, tc.expectedGov, result, "Incorrect governance data block for block %d", tc.blockNum) }) } diff --git a/kaiax/gov/headergov/impl/init.go b/kaiax/gov/headergov/impl/init.go index 9802e2e52..135d69573 100644 --- a/kaiax/gov/headergov/impl/init.go +++ b/kaiax/gov/headergov/impl/init.go @@ -1,6 +1,7 @@ package impl import ( + "fmt" "math/big" "sync" "sync/atomic" @@ -301,7 +302,7 @@ func GetGenesisGovBytes(config *params.ChainConfig) headergov.GovBytes { err = partialParamSet.Add(string(name), value) if err != nil { - panic(err) + panic(fmt.Errorf("failed to add param %s: %w", name, err)) } } diff --git a/kaiax/gov/headergov/impl/init_test.go b/kaiax/gov/headergov/impl/init_test.go index 69652dc48..1468a6b19 100644 --- a/kaiax/gov/headergov/impl/init_test.go +++ b/kaiax/gov/headergov/impl/init_test.go @@ -27,6 +27,12 @@ var ( extra = hexutil.MustDecode("0xd883010703846b6c617988676f312e31352e37856c696e757800000000000000f90164f85494571e53df607be97431a5bbefca1dffe5aef56f4d945cb1a7dccbd0dc446e3640898ede8820368554c89499fb17d324fa0e07f23b49d09028ac0919414db694b74ff9dea397fe9e231df545eb53fe2adf776cb2b841acb7fcc5152506250d1ea49745e7d0d5930157724b410e6e62e0885e7978c81863647d90700dcf3e5d0727cb886f2cc2c63f8f6f3910b4341b302a0aa06eae4500f8c9b841d79c07fbee8861585a71af08a867546320ba804c49c7a3c8641b4d235fd50d5a29bf72d20f3ff1ddfb945ff193d7938967be694f3e602a1cffdea686acf2b0ea01b841dfcf5b5608ca86bc92e7fa3d88a8b25840a629234614ecb312621234ed665ae562ee64ea09fcc88080aaab1ee095acf705d7cc495732682ffee23023ed41feb200b841fefc3b618b2384ea5c7c519ddecc666c19e8a600a6e30c5d9831941c0d5af78d28250bab36ce29202e667c9c1681fd9930aab002988c7228b64caab003bd998100") ) +func getTestChainConfig() *params.ChainConfig { + cc := params.MainnetChainConfig.Copy() + cc.Istanbul.Epoch = 100 + return cc +} + // genesis block must have the default governance params func newHeaderGovModule(t *testing.T, config *params.ChainConfig) *headerGovModule { var ( @@ -37,6 +43,10 @@ func newHeaderGovModule(t *testing.T, config *params.ChainConfig) *headerGovModu m = gov.GetDefaultGovernanceParamSet().ToMap() gov, _ = headergov.NewGovData(m).ToGovBytes() + chain = mocks.NewMockBlockChain(gomock.NewController(t)) + dbm = database.NewMemoryDBManager() + db = dbm.GetMemDB() + gov = GetGenesisGovBytes(config) ) WriteVoteDataBlockNums(db, StoredUint64Array{}) @@ -67,6 +77,7 @@ func newHeaderGovModule(t *testing.T, config *params.ChainConfig) *headerGovModu ValSet: valSet, ChainKv: db, ChainConfig: config, + NodeAddress: config.Governance.GoverningNode, }) require.NoError(t, err) WriteLowestVoteScannedEpochIdx(db, 0) @@ -123,8 +134,7 @@ func TestReadGovDataFromDB(t *testing.T) { } func TestInitialDB(t *testing.T) { - config := params.TestChainConfig.Copy() - config.Istanbul = ¶ms.IstanbulConfig{Epoch: 10} + config := getTestChainConfig() h := newHeaderGovModule(t, config) require.NotNil(t, h) From fa314ed8f540a0a9f6d63bb6ec76425f4cf2db2b Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Tue, 17 Dec 2024 16:14:39 +0900 Subject: [PATCH 07/12] Add migration test --- kaiax/gov/headergov/impl/getter_test.go | 3 +- kaiax/gov/headergov/impl/init.go | 13 +++- kaiax/gov/headergov/impl/init_test.go | 95 ++++++++++++++++++++++--- 3 files changed, 98 insertions(+), 13 deletions(-) diff --git a/kaiax/gov/headergov/impl/getter_test.go b/kaiax/gov/headergov/impl/getter_test.go index 0c6a067dd..5417ac76e 100644 --- a/kaiax/gov/headergov/impl/getter_test.go +++ b/kaiax/gov/headergov/impl/getter_test.go @@ -55,8 +55,7 @@ func TestEffectiveParams(t *testing.T) { } func TestEffectiveParamsPartial(t *testing.T) { - config := getTestChainConfig() - config.KoreCompatibleBlock = big.NewInt(0) + config := getTestChainConfigKore() h := newHeaderGovModule(t, config) testCases := []struct { diff --git a/kaiax/gov/headergov/impl/init.go b/kaiax/gov/headergov/impl/init.go index 135d69573..950dbb127 100644 --- a/kaiax/gov/headergov/impl/init.go +++ b/kaiax/gov/headergov/impl/init.go @@ -83,8 +83,6 @@ func (h *headerGovModule) Init(opts *InitOpts) error { return ErrZeroEpoch } - h.initSchema() - // init memory h.groupedVotes = make(map[uint64]headergov.VotesInEpoch) h.governances = make(map[uint64]headergov.GovData) @@ -92,6 +90,8 @@ func (h *headerGovModule) Init(opts *InitOpts) error { h.myVotes = make([]headergov.VoteData, 0) h.mu = &sync.RWMutex{} + h.initSchema() + govs := readGovDataFromDB(h.Chain, h.ChainKv) for blockNum, gov := range govs { h.AddGov(blockNum, gov) @@ -176,15 +176,22 @@ func (h *headerGovModule) PopMyVotes(idx int) { func (h *headerGovModule) scanAllVotesInEpoch(epochIdx uint64) map[uint64]headergov.VoteData { rangeStart := calcEpochStartBlock(epochIdx, h.epoch) rangeEnd := calcEpochStartBlock(epochIdx+1, h.epoch) + if currBlock := h.Chain.CurrentBlock().NumberU64(); rangeEnd > currBlock { + rangeEnd = currBlock + 1 // so currBlock is scanned + } votes := make(map[uint64]headergov.VoteData) for blockNum := rangeStart; blockNum < rangeEnd; blockNum++ { header := h.Chain.GetHeaderByNumber(blockNum) - if header == nil || len(header.Vote) == 0 { + if header == nil { logger.Warn("Missing header found", "num", blockNum) continue } + if len(header.Vote) == 0 { + continue + } + vote, err := headergov.VoteBytes(header.Vote).ToVoteData() if err != nil { logger.Error("Failed to parse vote", "num", blockNum, "err", err) diff --git a/kaiax/gov/headergov/impl/init_test.go b/kaiax/gov/headergov/impl/init_test.go index 1468a6b19..14eca9d76 100644 --- a/kaiax/gov/headergov/impl/init_test.go +++ b/kaiax/gov/headergov/impl/init_test.go @@ -1,6 +1,7 @@ package impl import ( + "encoding/json" "math/big" "reflect" "strings" @@ -15,6 +16,7 @@ import ( "github.com/kaiachain/kaia/kaiax/gov" "github.com/kaiachain/kaia/kaiax/gov/headergov" mock_valset "github.com/kaiachain/kaia/kaiax/valset/mock" + "github.com/kaiachain/kaia/log" "github.com/kaiachain/kaia/params" "github.com/kaiachain/kaia/storage/database" "github.com/kaiachain/kaia/work/mocks" @@ -33,6 +35,13 @@ func getTestChainConfig() *params.ChainConfig { return cc } +func getTestChainConfigKore() *params.ChainConfig { + cc := params.MainnetChainConfig.Copy() + cc.Istanbul.Epoch = 100 + cc.KoreCompatibleBlock = common.Big0 + return cc +} + // genesis block must have the default governance params func newHeaderGovModule(t *testing.T, config *params.ChainConfig) *headerGovModule { var ( @@ -40,20 +49,14 @@ func newHeaderGovModule(t *testing.T, config *params.ChainConfig) *headerGovModu valSet = mock_valset.NewMockValsetModule(gomock.NewController(t)) dbm = database.NewMemoryDBManager() db = dbm.GetMemDB() - - m = gov.GetDefaultGovernanceParamSet().ToMap() - gov, _ = headergov.NewGovData(m).ToGovBytes() - chain = mocks.NewMockBlockChain(gomock.NewController(t)) - dbm = database.NewMemoryDBManager() - db = dbm.GetMemDB() - gov = GetGenesisGovBytes(config) + b = GetGenesisGovBytes(config) ) WriteVoteDataBlockNums(db, StoredUint64Array{}) WriteGovDataBlockNums(db, StoredUint64Array{0}) genesisHeader := &types.Header{ Number: big.NewInt(0), - Governance: gov, + Governance: b, } dbm.WriteHeader(genesisHeader) @@ -264,3 +267,79 @@ func TestMainnetGenesisHash(t *testing.T) { t.Errorf("Generated hash is not equal to Mainnet's hash. Want %v, Have %v", mainnetHash.String(), block.Hash().String()) } } + +func makeEmptyBlock(num uint64) *types.Block { + return types.NewBlockWithHeader(&types.Header{Number: big.NewInt(int64(num))}) +} + +func TestMigration(t *testing.T) { + log.EnableLogForTest(log.LvlCrit, log.LvlDebug) + var ( + config = getTestChainConfigKore() + mockChain = mocks.NewMockBlockChain(gomock.NewController(t)) + dbm = database.NewMemoryDBManager() + db = dbm.GetMemDB() + governingNode = config.Governance.GoverningNode + vote50, _ = headergov.NewVoteData(governingNode, string(gov.GovernanceUnitPrice), uint64(100)).ToVoteBytes() + vote150, _ = headergov.NewVoteData(governingNode, string(gov.GovernanceUnitPrice), uint64(200)).ToVoteBytes() + vote200, _ = headergov.NewVoteData(governingNode, string(gov.GovernanceUnitPrice), uint64(300)).ToVoteBytes() + vote222, _ = headergov.NewVoteData(governingNode, string(gov.GovernanceUnitPrice), uint64(400)).ToVoteBytes() + gov0 = GetGenesisGovBytes(config) + gov100, _ = headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: uint64(100)}).ToGovBytes() + gov200, _ = headergov.NewGovData(gov.PartialParamSet{gov.GovernanceUnitPrice: uint64(200)}).ToGovBytes() + votes = map[uint64][]byte{50: vote50, 150: vote150, 200: vote200, 222: vote222} + govs = map[uint64][]byte{0: gov0, 100: gov100, 200: gov200} + expected = map[uint64]uint64{0: config.UnitPrice, 100: config.UnitPrice, 200: 100} + ) + + // 1. Setup DB and Headers + legacyIdxHistory, _ := json.Marshal([]uint64{0, 100, 200}) + db.Put(legacyIdxHistoryKey, legacyIdxHistory) + + for i := uint64(0); i <= 222; i++ { + header := &types.Header{Number: big.NewInt(int64(i)), Vote: votes[i], Governance: govs[i]} + mockChain.EXPECT().GetHeaderByNumber(i).Return(header).AnyTimes() + } + mockChain.EXPECT().CurrentBlock().Return(makeEmptyBlock(222)).AnyTimes() + + assert.Nil(t, ReadLowestVoteScannedEpochIdx(db)) + assert.Nil(t, ReadVoteDataBlockNums(db)) + assert.Nil(t, ReadGovDataBlockNums(db)) + assert.Equal(t, StoredUint64Array{0, 100, 200}, ReadLegacyIdxHistory(db)) + + // 2. Run Init() and check resulting initial schema + h := NewHeaderGovModule() + h.Init(&InitOpts{ + ChainConfig: config, + ChainKv: db, + Chain: mockChain, + NodeAddress: config.Governance.GoverningNode, + }) + + assert.Equal(t, uint64(2), *ReadLowestVoteScannedEpochIdx(db)) + assert.Equal(t, StoredUint64Array{200, 222}, ReadVoteDataBlockNums(db)) + assert.Equal(t, []uint64{200, 222}, h.VoteBlockNums()) + assert.Equal(t, StoredUint64Array{0, 100, 200}, ReadGovDataBlockNums(db)) + assert.Equal(t, []uint64{0, 100, 200}, h.GovBlockNums()) + + // 3. Before migration, check GetParamSet() results + for num, expectedValue := range expected { + paramSet := h.GetParamSet(num) + assert.Equal(t, expectedValue, paramSet.UnitPrice, "wrong at block %d", num) + } + + // 4. Run migrate() and check resulting migrated schema + h.wg.Add(1) + h.migrate() + + assert.Equal(t, uint64(0), *ReadLowestVoteScannedEpochIdx(db)) + assert.Equal(t, StoredUint64Array{50, 150, 200, 222}, ReadVoteDataBlockNums(db)) + assert.Equal(t, []uint64{50, 150, 200, 222}, h.VoteBlockNums()) + assert.Equal(t, StoredUint64Array{0, 100, 200}, ReadGovDataBlockNums(db)) + assert.Equal(t, []uint64{0, 100, 200}, h.GovBlockNums()) + + for num, expectedValue := range expected { + paramSet := h.GetParamSet(num) + assert.Equal(t, expectedValue, paramSet.UnitPrice, "wrong at block %d", num) + } +} From 75e2ecb92e1d7b0b3a0350ba1586ae76609ba0cf Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Tue, 17 Dec 2024 18:53:40 +0900 Subject: [PATCH 08/12] Add TestAccumulateVotesInEpoch --- kaiax/gov/headergov/impl/init_test.go | 39 +++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/kaiax/gov/headergov/impl/init_test.go b/kaiax/gov/headergov/impl/init_test.go index 14eca9d76..53b83c960 100644 --- a/kaiax/gov/headergov/impl/init_test.go +++ b/kaiax/gov/headergov/impl/init_test.go @@ -144,7 +144,7 @@ func TestInitialDB(t *testing.T) { assert.Nil(t, ReadLegacyIdxHistory(h.ChainKv)) assert.Equal(t, StoredUint64Array{0}, ReadGovDataBlockNums(h.ChainKv)) - assert.Nil(t, StoredUint64Array(nil), ReadVoteDataBlockNums(h.ChainKv)) + assert.Equal(t, StoredUint64Array{}, ReadVoteDataBlockNums(h.ChainKv)) assert.Equal(t, uint64(0), *ReadLowestVoteScannedEpochIdx(h.ChainKv)) } @@ -272,6 +272,40 @@ func makeEmptyBlock(num uint64) *types.Block { return types.NewBlockWithHeader(&types.Header{Number: big.NewInt(int64(num))}) } +func TestAccumulateVotesInEpoch(t *testing.T) { + log.EnableLogForTest(log.LvlCrit, log.LvlDebug) + var ( + config = getTestChainConfigKore() + mockChain = mocks.NewMockBlockChain(gomock.NewController(t)) + dbm = database.NewMemoryDBManager() + db = dbm.GetMemDB() + ) + + for i := uint64(0); i <= 222; i++ { + header := makeEmptyBlock(i).Header() + mockChain.EXPECT().GetHeaderByNumber(i).Return(header).AnyTimes() + } + mockChain.EXPECT().CurrentBlock().Return(makeEmptyBlock(222)).AnyTimes() + assert.Nil(t, ReadLowestVoteScannedEpochIdx(db)) + + h := NewHeaderGovModule() + err := h.Init(&InitOpts{ + ChainConfig: config, + ChainKv: db, + Chain: mockChain, + NodeAddress: config.Governance.GoverningNode, + }) + require.Nil(t, err) + // Init calls h.accumulateVotesInEpoch(2) + assert.Equal(t, uint64(2), *ReadLowestVoteScannedEpochIdx(db)) + + h.accumulateVotesInEpoch(1) + assert.Equal(t, uint64(1), *ReadLowestVoteScannedEpochIdx(db)) + + h.accumulateVotesInEpoch(0) + assert.Equal(t, uint64(0), *ReadLowestVoteScannedEpochIdx(db)) +} + func TestMigration(t *testing.T) { log.EnableLogForTest(log.LvlCrit, log.LvlDebug) var ( @@ -309,12 +343,13 @@ func TestMigration(t *testing.T) { // 2. Run Init() and check resulting initial schema h := NewHeaderGovModule() - h.Init(&InitOpts{ + err := h.Init(&InitOpts{ ChainConfig: config, ChainKv: db, Chain: mockChain, NodeAddress: config.Governance.GoverningNode, }) + require.Nil(t, err) assert.Equal(t, uint64(2), *ReadLowestVoteScannedEpochIdx(db)) assert.Equal(t, StoredUint64Array{200, 222}, ReadVoteDataBlockNums(db)) From 21fb1479f08a5457f340d3955e2dca7e38ab5506 Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Tue, 24 Dec 2024 09:50:01 +0900 Subject: [PATCH 09/12] Rename recently added getter --- kaiax/gov/headergov/impl/consensus.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kaiax/gov/headergov/impl/consensus.go b/kaiax/gov/headergov/impl/consensus.go index 5696e2ec6..080fafac0 100644 --- a/kaiax/gov/headergov/impl/consensus.go +++ b/kaiax/gov/headergov/impl/consensus.go @@ -150,7 +150,7 @@ func (h *headerGovModule) checkConsistency(blockNum uint64, vote headergov.VoteD //nolint:exhaustive switch vote.Name() { case gov.GovernanceGoverningNode: - params := h.EffectiveParamSet(blockNum) + params := h.GetParamSet(blockNum) // skip the consistency check if governingMode is non-single. if params.GovernanceMode != "single" { @@ -196,7 +196,7 @@ func (h *headerGovModule) checkConsistency(blockNum uint64, vote headergov.VoteD return ErrUpperBoundBaseFee } case gov.AddValidator, gov.RemoveValidator: - params := h.EffectiveParamSet(blockNum) + params := h.GetParamSet(blockNum) if params.GovernanceMode != "single" { return nil From cfc31a31f31602470dff9c9b4e6325ff03b45946 Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Thu, 26 Dec 2024 14:00:23 +0900 Subject: [PATCH 10/12] Rename recently added getter --- consensus/istanbul/backend/snapshot.go | 2 +- consensus/istanbul/backend/validator.go | 2 +- kaiax/valset/impl/execution.go | 2 +- kaiax/valset/impl/execution_test.go | 4 ++-- kaiax/valset/impl/getter_context.go | 2 +- kaiax/valset/impl/getter_council.go | 2 +- kaiax/valset/impl/getter_demote.go | 2 +- kaiax/valset/impl/getter_demote_test.go | 2 +- kaiax/valset/impl/getter_proposers_test.go | 2 +- kaiax/valset/impl/init_test.go | 4 ++-- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/consensus/istanbul/backend/snapshot.go b/consensus/istanbul/backend/snapshot.go index 911d67546..f0872a443 100644 --- a/consensus/istanbul/backend/snapshot.go +++ b/consensus/istanbul/backend/snapshot.go @@ -456,7 +456,7 @@ func (sb *backend) snapshot(chain consensus.ChainReader, number uint64, hash com return nil, err } - pset := sb.govModule.EffectiveParamSet(snap.Number) + pset := sb.govModule.GetParamSet(snap.Number) snap, err = snap.apply(headers, sb.governance, sb.govModule, sb.address, pset.ProposerPolicy, chain, sb.stakingModule, writable) if err != nil { return nil, err diff --git a/consensus/istanbul/backend/validator.go b/consensus/istanbul/backend/validator.go index aa1eb7606..d09543f3e 100644 --- a/consensus/istanbul/backend/validator.go +++ b/consensus/istanbul/backend/validator.go @@ -44,7 +44,7 @@ func (sb *backend) GetCommitteeStateByRound(num uint64, round uint64) (*istanbul return nil, err } - committeeSize := sb.govModule.EffectiveParamSet(num).CommitteeSize + committeeSize := sb.govModule.GetParamSet(num).CommitteeSize return istanbul.NewRoundCommitteeState(blockValSet, committeeSize, committee, proposer), nil } diff --git a/kaiax/valset/impl/execution.go b/kaiax/valset/impl/execution.go index 31eeb27a0..4b6e6ba19 100644 --- a/kaiax/valset/impl/execution.go +++ b/kaiax/valset/impl/execution.go @@ -33,7 +33,7 @@ func (v *ValsetModule) PostInsertBlock(block *types.Block) error { if err != nil { return err } - governingNode := v.GovModule.EffectiveParamSet(num).GoverningNode + governingNode := v.GovModule.GetParamSet(num).GoverningNode if applyVote(header, council, governingNode) { insertValidatorVoteBlockNums(v.ChainKv, num) writeCouncil(v.ChainKv, num, council.List()) diff --git a/kaiax/valset/impl/execution_test.go b/kaiax/valset/impl/execution_test.go index 1ffac1d18..d7a0bb80e 100644 --- a/kaiax/valset/impl/execution_test.go +++ b/kaiax/valset/impl/execution_test.go @@ -66,8 +66,8 @@ func TestPostInsertBlock(t *testing.T) { writeValidatorVoteBlockNums(db, []uint64{0}) writeLowestScannedVoteNum(db, 0) mockChain.EXPECT().GetHeaderByNumber(uint64(0)).Return(makeGenesisBlock(genesisCouncil).Header()).AnyTimes() - mockGov.EXPECT().EffectiveParamSet(uint64(1)).Return(pset).AnyTimes() - mockGov.EXPECT().EffectiveParamSet(uint64(2)).Return(pset).AnyTimes() + mockGov.EXPECT().GetParamSet(uint64(1)).Return(pset).AnyTimes() + mockGov.EXPECT().GetParamSet(uint64(2)).Return(pset).AnyTimes() // Ineffective vote (adding already existing address) assert.NoError(t, v.PostInsertBlock(block1)) diff --git a/kaiax/valset/impl/getter_context.go b/kaiax/valset/impl/getter_context.go index f083517bd..48c2b8b9f 100644 --- a/kaiax/valset/impl/getter_context.go +++ b/kaiax/valset/impl/getter_context.go @@ -65,7 +65,7 @@ func (v *ValsetModule) getBlockContext(num uint64) (*blockContext, error) { prevHeader: prevHeader, prevProposer: prevProposer, rules: v.Chain.Config().Rules(new(big.Int).SetUint64(num)), - pset: v.GovModule.EffectiveParamSet(num), + pset: v.GovModule.GetParamSet(num), }, nil } diff --git a/kaiax/valset/impl/getter_council.go b/kaiax/valset/impl/getter_council.go index cd270e700..3361c7ac3 100644 --- a/kaiax/valset/impl/getter_council.go +++ b/kaiax/valset/impl/getter_council.go @@ -157,7 +157,7 @@ func (v *ValsetModule) applyBlock(council *valset.AddressSet, num uint64, write if header == nil { return errNoHeader } - governingNode := v.GovModule.EffectiveParamSet(num).GoverningNode + governingNode := v.GovModule.GetParamSet(num).GoverningNode if applyVote(header, council, governingNode) && write { insertValidatorVoteBlockNums(v.ChainKv, num) writeCouncil(v.ChainKv, num, council.List()) diff --git a/kaiax/valset/impl/getter_demote.go b/kaiax/valset/impl/getter_demote.go index 44c3afab2..7840f9444 100644 --- a/kaiax/valset/impl/getter_demote.go +++ b/kaiax/valset/impl/getter_demote.go @@ -32,7 +32,7 @@ func (v *ValsetModule) getDemotedValidators(council *valset.AddressSet, num uint return valset.NewAddressSet(nil), nil } - pset := v.GovModule.EffectiveParamSet(num) + pset := v.GovModule.GetParamSet(num) rules := v.Chain.Config().Rules(new(big.Int).SetUint64(num)) switch istanbul.ProposerPolicy(pset.ProposerPolicy) { diff --git a/kaiax/valset/impl/getter_demote_test.go b/kaiax/valset/impl/getter_demote_test.go index 6b6138130..76d6c81bb 100644 --- a/kaiax/valset/impl/getter_demote_test.go +++ b/kaiax/valset/impl/getter_demote_test.go @@ -88,7 +88,7 @@ func TestGetDemotedValidators(t *testing.T) { mockChain.EXPECT().Config().Return(config).Times(1) pset.ProposerPolicy = uint64(tc.policy) - mockGov.EXPECT().EffectiveParamSet(gomock.Any()).Return(pset).Times(1) + mockGov.EXPECT().GetParamSet(gomock.Any()).Return(pset).Times(1) mockStaking.EXPECT().GetStakingInfo(gomock.Any()).Return(si, nil).AnyTimes() demoted, err := v.getDemotedValidators(valset.NewAddressSet(council), 1) diff --git a/kaiax/valset/impl/getter_proposers_test.go b/kaiax/valset/impl/getter_proposers_test.go index e22603021..dcd516fc1 100644 --- a/kaiax/valset/impl/getter_proposers_test.go +++ b/kaiax/valset/impl/getter_proposers_test.go @@ -100,7 +100,7 @@ func TestGetProposers_GetRemoveVotesInInterval(t *testing.T) { writeCouncil(v.ChainKv, 0, genesisCouncil) // Mock gov module - mockGovModule.EXPECT().EffectiveParamSet(gomock.Any()).Return(gov.ParamSet{ + mockGovModule.EXPECT().GetParamSet(gomock.Any()).Return(gov.ParamSet{ StakingUpdateInterval: 1, ProposerUpdateInterval: params.DefaultProposerRefreshInterval, ProposerPolicy: uint64(params.WeightedRandom), diff --git a/kaiax/valset/impl/init_test.go b/kaiax/valset/impl/init_test.go index 4d9fce198..ac7a2e1eb 100644 --- a/kaiax/valset/impl/init_test.go +++ b/kaiax/valset/impl/init_test.go @@ -54,7 +54,7 @@ func TestStartStop(t *testing.T) { ) defer ctrl.Finish() - mockGov.EXPECT().EffectiveParamSet(gomock.Any()).Return(gov.ParamSet{}).AnyTimes() + mockGov.EXPECT().GetParamSet(gomock.Any()).Return(gov.ParamSet{}).AnyTimes() mockChain.EXPECT().CurrentBlock().Return(current).AnyTimes() mockChain.EXPECT().GetHeaderByNumber(uint64(0)).Return(genesis).AnyTimes() for i := uint64(1); i <= current.NumberU64(); i++ { @@ -149,7 +149,7 @@ func TestMigration(t *testing.T) { ) defer ctrl.Finish() - mockGov.EXPECT().EffectiveParamSet(gomock.Any()).Return(pset).AnyTimes() + mockGov.EXPECT().GetParamSet(gomock.Any()).Return(pset).AnyTimes() mockChain.EXPECT().CurrentBlock().Return(block2050).AnyTimes() mockChain.EXPECT().GetHeaderByNumber(uint64(0)).Return(genesis).AnyTimes() for i := uint64(1); i <= 2050; i++ { From 21f370671d26df3c5c64416588ccc006d8b7015b Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Thu, 26 Dec 2024 15:08:17 +0900 Subject: [PATCH 11/12] Add logs --- kaiax/gov/error.go | 4 +++- kaiax/gov/headergov/error.go | 8 +++++++- kaiax/gov/headergov/gov.go | 1 + kaiax/gov/headergov/impl/getter.go | 1 + kaiax/gov/headergov/impl/init.go | 2 +- kaiax/gov/headergov/vote.go | 4 ++++ 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/kaiax/gov/error.go b/kaiax/gov/error.go index fcab17555..48061af94 100644 --- a/kaiax/gov/error.go +++ b/kaiax/gov/error.go @@ -1,6 +1,8 @@ package gov -import "errors" +import ( + "errors" +) var ( ErrInitNil = errors.New("cannot init gov module because of nil") diff --git a/kaiax/gov/headergov/error.go b/kaiax/gov/headergov/error.go index be4bccdc6..f37c05fce 100644 --- a/kaiax/gov/headergov/error.go +++ b/kaiax/gov/headergov/error.go @@ -1,6 +1,12 @@ package headergov -import "errors" +import ( + "errors" + + "github.com/kaiachain/kaia/log" +) + +var logger = log.NewModuleLogger(log.KaiaxGov) var ( ErrInvalidRlp = errors.New("invalid rlp") diff --git a/kaiax/gov/headergov/gov.go b/kaiax/gov/headergov/gov.go index 015743ec5..6bbf2d352 100644 --- a/kaiax/gov/headergov/gov.go +++ b/kaiax/gov/headergov/gov.go @@ -26,6 +26,7 @@ func NewGovData(m gov.PartialParamSet) GovData { for name, value := range m { err := items.Add(string(name), value) if err != nil { + logger.Error("Invalid param", "name", name, "value", value) return nil } } diff --git a/kaiax/gov/headergov/impl/getter.go b/kaiax/gov/headergov/impl/getter.go index 023a7e5bf..13427787b 100644 --- a/kaiax/gov/headergov/impl/getter.go +++ b/kaiax/gov/headergov/impl/getter.go @@ -16,6 +16,7 @@ func (h *headerGovModule) GetParamSet(blockNum uint64) gov.ParamSet { gh := h.history gp, err := gh.Search(prevEpochStart) if err != nil { + logger.Warn("No param set", "blockNum", blockNum, "prevEpochStart", prevEpochStart) return *gov.GetDefaultGovernanceParamSet() } return gp diff --git a/kaiax/gov/headergov/impl/init.go b/kaiax/gov/headergov/impl/init.go index 950dbb127..006c257c9 100644 --- a/kaiax/gov/headergov/impl/init.go +++ b/kaiax/gov/headergov/impl/init.go @@ -227,7 +227,7 @@ func (h *headerGovModule) accumulateVotesInEpoch(epochIdx uint64) { } WriteLowestVoteScannedEpochIdx(h.ChainKv, epochIdx) - logger.Info("Accumulated votes", "epochIdx", epochIdx, "lowestScanned", epochIdx) + logger.Info("Accumulated votes", "epochIdx", epochIdx) } func readVoteDataFromDB(chain chain, db database.Database) map[uint64]headergov.VoteData { diff --git a/kaiax/gov/headergov/vote.go b/kaiax/gov/headergov/vote.go index 856a87a70..43e56e827 100644 --- a/kaiax/gov/headergov/vote.go +++ b/kaiax/gov/headergov/vote.go @@ -30,20 +30,24 @@ func NewVoteData(voter common.Address, name string, value any) VoteData { if !ok { param, ok = gov.ValidatorParams[gov.ParamName(name)] if !ok { + logger.Error("Invalid vote name", "name", name) return nil } } if param.VoteForbidden { + logger.Error("Vote is forbidden", "name", name) return nil } cv, err := param.Canonicalizer(value) if err != nil { + logger.Error("Canonicalize error", "name", name, "value", value, "err", err) return nil } if !param.FormatChecker(cv) { + logger.Error("Format check error", "name", name, "value", value) return nil } From d3e29529e6fff5ab599223014bcc0931bc1b103c Mon Sep 17 00:00:00 2001 From: Chihyun Song Date: Thu, 26 Dec 2024 16:56:13 +0900 Subject: [PATCH 12/12] Add migrate complete log --- kaiax/gov/headergov/impl/init.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kaiax/gov/headergov/impl/init.go b/kaiax/gov/headergov/impl/init.go index 006c257c9..5a7dd6b3c 100644 --- a/kaiax/gov/headergov/impl/init.go +++ b/kaiax/gov/headergov/impl/init.go @@ -158,6 +158,10 @@ func (h *headerGovModule) migrate() { border -= 1 h.accumulateVotesInEpoch(border) } + + if border == 0 { + logger.Info("HeaderGovModule migrate complete") + } } func (h *headerGovModule) isKoreHF(num uint64) bool {