Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[staking] fix alias for non-stop node #4503

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions action/protocol/staking/vote_reviser.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type (
ReviseConfig struct {
VoteWeight genesis.VoteWeightCalConsts
ReviseHeights []uint64
FixAliasForNonStopHeight uint64
CorrectCandsHeight uint64
SelfStakeBucketReviseHeight uint64
CorrectCandSelfStakeHeight uint64
Expand All @@ -42,7 +43,23 @@ func NewVoteReviser(cfg ReviseConfig) *VoteReviser {
// Revise recalculate candidate votes on preset revising height.
func (vr *VoteReviser) Revise(ctx protocol.FeatureCtx, csm CandidateStateManager, height uint64) error {
if !vr.isCacheExist(height) {
cands, _, err := newCandidateStateReader(csm.SM()).getAllCandidates()
var (
cands CandidateList
err error
)
if vr.fixAliasForNonStopNode(height) {
name, operator, owners, err := readCandCenterStateFromStateDB(csm.SM())
if err != nil {
return err
}
base := csm.DirtyView().candCenter.base
if err := base.loadNameOperatorMapOwnerList(name, operator, owners); err != nil {
return err
}
cands = base.all()
} else {
cands, _, err = newCandidateStateReader(csm.SM()).getAllCandidates()
}
switch {
case errors.Cause(err) == state.ErrStateNotExist:
case err != nil:
Expand Down Expand Up @@ -71,22 +88,30 @@ func (vr *VoteReviser) Revise(ctx protocol.FeatureCtx, csm CandidateStateManager
return err
}
}
vr.storeToCache(height, cands)
if vr.needRevise(height) {
vr.storeToCache(height, cands)
}
}
if vr.needRevise(height) {
return vr.flush(height, csm)
}
return vr.flush(height, csm)
return nil
}

func (vr *VoteReviser) correctAliasCands(csm CandidateStateManager, cands CandidateList) (CandidateList, error) {
var retval CandidateList
for _, c := range csm.DirtyView().candCenter.base.nameMap {
var (
retval CandidateList
base = csm.DirtyView().candCenter.base
)
for _, c := range base.nameMap {
retval = append(retval, c)
}
for _, c := range csm.DirtyView().candCenter.base.operatorMap {
for _, c := range base.operatorMap {
retval = append(retval, c)
}
sort.Sort(retval)
ownerMap := map[string]*Candidate{}
for _, cand := range csm.DirtyView().candCenter.base.owners {
for _, cand := range base.owners {
ownerMap[cand.Owner.String()] = cand
}
for _, c := range cands {
Expand Down Expand Up @@ -166,13 +191,19 @@ func (vr *VoteReviser) isCacheExist(height uint64) bool {

// NeedRevise returns true if height needs revise
func (vr *VoteReviser) NeedRevise(height uint64) bool {
return vr.needRevise(height) || vr.fixAliasForNonStopNode(height)
}
func (vr *VoteReviser) needRevise(height uint64) bool {
return slices.Contains(vr.cfg.ReviseHeights, height) ||
vr.shouldReviseSelfStakeBuckets(height) ||
vr.shouldReviseAlias(height) ||
vr.shouldCorrectCandSelfStake(height)
}

// NeedCorrectCands returns true if height needs to correct candidates
func (vr *VoteReviser) fixAliasForNonStopNode(height uint64) bool {
return height == vr.cfg.FixAliasForNonStopHeight
}

func (vr *VoteReviser) shouldReviseAlias(height uint64) bool {
return height == vr.cfg.CorrectCandsHeight
}
Expand Down
3 changes: 3 additions & 0 deletions blockchain/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func defaultConfig() Genesis {
NumDelegates: 24,
NumCandidateDelegates: 36,
TimeBasedRotation: false,
FixAliasForNonStopHeight: 21542761,
MinBlocksForBlobRetention: 345600,
PacificBlockHeight: 432001,
AleutianBlockHeight: 864001,
Expand Down Expand Up @@ -184,6 +185,8 @@ type (
NumCandidateDelegates uint64 `yaml:"numCandidateDelegates"`
// TimeBasedRotation is the flag to enable rotating delegates' time slots on a block height
TimeBasedRotation bool `yaml:"timeBasedRotation"`
// FixAliasForNonStopHeight is the height to fix candidate alias for a non-stopping node
FixAliasForNonStopHeight uint64 `yaml:"fixAliasForNonStopHeight"`
// MinBlocksForBlobRetention is the minimum number of blocks for blob retention
MinBlocksForBlobRetention uint64 `yaml:"minBlocksForBlobRetention"`
// PacificBlockHeight is the start height of using the logic of Pacific version
Expand Down
1 change: 1 addition & 0 deletions chainservice/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ func (builder *Builder) registerStakingProtocol() error {
Revise: staking.ReviseConfig{
VoteWeight: builder.cfg.Genesis.VoteWeightCalConsts,
ReviseHeights: []uint64{builder.cfg.Genesis.GreenlandBlockHeight, builder.cfg.Genesis.HawaiiBlockHeight},
FixAliasForNonStopHeight: builder.cfg.Genesis.FixAliasForNonStopHeight,
CorrectCandsHeight: builder.cfg.Genesis.OkhotskBlockHeight,
SelfStakeBucketReviseHeight: builder.cfg.Genesis.UpernavikBlockHeight,
CorrectCandSelfStakeHeight: builder.cfg.Genesis.VanuatuBlockHeight,
Expand Down
10 changes: 4 additions & 6 deletions state/factory/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func (sf *factory) newWorkingSet(ctx context.Context, height uint64) (*workingSe
flusher, err := db.NewKVStoreFlusher(
sf.dao,
batch.NewCachedBatch(),
sf.flusherOptions(!g.IsEaster(height))...,
sf.flusherOptions(!g.IsEaster(height), height == g.FixAliasForNonStopHeight)...,
)
if err != nil {
return nil, err
Expand All @@ -290,16 +290,14 @@ func (sf *factory) newWorkingSet(ctx context.Context, height uint64) (*workingSe
return newWorkingSet(height, store), nil
}

func (sf *factory) flusherOptions(preEaster bool) []db.KVStoreFlusherOption {
func (sf *factory) flusherOptions(preEaster, fixNonStop bool) []db.KVStoreFlusherOption {
opts := []db.KVStoreFlusherOption{
db.SerializeFilterOption(func(wi *batch.WriteInfo) bool {
if wi.Namespace() == ArchiveTrieNamespace {
return true
}
if wi.Namespace() != evm.CodeKVNameSpace && wi.Namespace() != staking.CandsMapNS {
return false
}
return preEaster
return preEaster && (wi.Namespace() == evm.CodeKVNameSpace || wi.Namespace() == staking.CandsMapNS) ||
fixNonStop && (wi.Namespace() == staking.CandsMapNS)
}),
db.SerializeOption(func(wi *batch.WriteInfo) []byte {
if preEaster {
Expand Down
21 changes: 11 additions & 10 deletions state/factory/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (sdb *stateDB) newWorkingSet(ctx context.Context, height uint64) (*workingS
flusher, err := db.NewKVStoreFlusher(
sdb.dao,
batch.NewCachedBatch(),
sdb.flusherOptions(!g.IsEaster(height))...,
sdb.flusherOptions(!g.IsEaster(height), height == g.FixAliasForNonStopHeight)...,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -380,7 +380,7 @@ func (sdb *stateDB) ReadView(name string) (interface{}, error) {
// private trie constructor functions
//======================================

func (sdb *stateDB) flusherOptions(preEaster bool) []db.KVStoreFlusherOption {
func (sdb *stateDB) flusherOptions(preEaster, fixNonStop bool) []db.KVStoreFlusherOption {
opts := []db.KVStoreFlusherOption{
db.SerializeOption(func(wi *batch.WriteInfo) []byte {
if preEaster {
Expand All @@ -389,15 +389,16 @@ func (sdb *stateDB) flusherOptions(preEaster bool) []db.KVStoreFlusherOption {
return wi.Serialize()
}),
}
if !preEaster {
return opts
if preEaster || fixNonStop {
opts = append(
opts,
db.SerializeFilterOption(func(wi *batch.WriteInfo) bool {
return preEaster && (wi.Namespace() == evm.CodeKVNameSpace || wi.Namespace() == staking.CandsMapNS) ||
fixNonStop && (wi.Namespace() == staking.CandsMapNS)
}),
)
}
return append(
opts,
db.SerializeFilterOption(func(wi *batch.WriteInfo) bool {
return wi.Namespace() == evm.CodeKVNameSpace || wi.Namespace() == staking.CandsMapNS
}),
)
return opts
}

func (sdb *stateDB) state(ns string, addr []byte, s interface{}) error {
Expand Down
Loading