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

Change candidates/kickoutList state DB implementation #1858

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 11 additions & 3 deletions action/protocol/poll/governance_protocol.go
Expand Up @@ -152,15 +152,23 @@ func (p *governanceChainCommitteeProtocol) CreatePreStates(ctx context.Context,
if err != nil {
return err
}
return setKickoutBlackList(sm, unqualifiedList)
return setNextEpochBlacklist(sm, unqualifiedList)
} else if blkCtx.BlockHeight == epochStartHeight && hu.IsPost(config.Easter, epochStartHeight) {
koseoyoung marked this conversation as resolved.
Show resolved Hide resolved
if err := shiftCandidates(sm); err != nil {
prevHeight, err := shiftCandidates(sm)
if err != nil {
return err
}
if blkCtx.BlockHeight == 1 {
koseoyoung marked this conversation as resolved.
Show resolved Hide resolved
return nil
}
return shiftKickoutList(sm)
afterHeight, err := shiftKickoutList(sm)
if err != nil {
return err
}
if prevHeight != afterHeight {
return errors.Wrap(ErrInconsistentHeight, "shifting candidate height is not same as shifting kickout height")
}
return nil
}
return nil
}
Expand Down
34 changes: 18 additions & 16 deletions action/protocol/poll/governance_protocol_test.go
Expand Up @@ -74,7 +74,7 @@ func initConstruct(ctrl *gomock.Controller) (Protocol, context.Context, protocol
if err != nil {
return 0, err
}
val, err := cb.Get("state", cfg.Key)
val, err := cb.Get(cfg.Namespace, cfg.Key)
if err != nil {
return 0, state.ErrStateNotExist
}
Expand All @@ -90,7 +90,7 @@ func initConstruct(ctrl *gomock.Controller) (Protocol, context.Context, protocol
if err != nil {
return 0, err
}
cb.Put("state", cfg.Key, ss, "failed to put state")
cb.Put(cfg.Namespace, cfg.Key, ss, "failed to put state")
return 0, nil
}).AnyTimes()
sm.EXPECT().Snapshot().Return(1).AnyTimes()
Expand Down Expand Up @@ -182,7 +182,7 @@ func TestCreateGenesisStates(t *testing.T) {
require.NoError(p.CreateGenesisStates(ctx, sm))
var sc state.CandidateList
candKey := candidatesutil.ConstructKey(candidatesutil.NxtCandidateKey)
_, err = sm.State(&sc, protocol.KeyOption(candKey[:]))
_, err = sm.State(&sc, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
candidates, err := state.CandidatesToMap(sc)
require.NoError(err)
Expand Down Expand Up @@ -266,7 +266,7 @@ func TestCreatePreStates(t *testing.T) {
require.NoError(psc.CreatePreStates(ctx, sm)) // shift
bl := &vote.Blacklist{}
candKey := candidatesutil.ConstructKey(candidatesutil.CurKickoutKey)
_, err := sm.State(bl, protocol.KeyOption(candKey[:]))
_, err := sm.State(bl, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
expected := test[epochNum]
require.Equal(len(expected), len(bl.BlacklistInfos))
Expand All @@ -289,7 +289,7 @@ func TestCreatePreStates(t *testing.T) {

bl := &vote.Blacklist{}
candKey := candidatesutil.ConstructKey(candidatesutil.NxtKickoutKey)
_, err = sm.State(bl, protocol.KeyOption(candKey[:]))
_, err = sm.State(bl, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
expected := test[epochNum+1]
require.Equal(len(expected), len(bl.BlacklistInfos))
Expand Down Expand Up @@ -332,7 +332,7 @@ func TestHandle(t *testing.T) {
require.NoError(p2.CreateGenesisStates(ctx2, sm2))
var sc2 state.CandidateList
candKey := candidatesutil.ConstructKey(candidatesutil.NxtCandidateKey)
_, err = sm2.State(&sc2, protocol.KeyOption(candKey[:]))
_, err = sm2.State(&sc2, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
act2 := action.NewPutPollResult(1, 1, sc2)
elp = bd.SetGasLimit(uint64(100000)).
Expand All @@ -345,7 +345,8 @@ func TestHandle(t *testing.T) {
require.NoError(err)
require.NotNil(receipt)

require.NoError(shiftCandidates(sm2))
_, err = shiftCandidates(sm2)
require.NoError(err)
candidates, _, err := candidatesutil.CandidatesFromDB(sm2, false)
require.NoError(err)
require.Equal(2, len(candidates))
Expand Down Expand Up @@ -384,7 +385,7 @@ func TestProtocol_Validate(t *testing.T) {
require.NoError(p2.CreateGenesisStates(ctx2, sm2))
var sc2 state.CandidateList
candKey := candidatesutil.ConstructKey(candidatesutil.NxtCandidateKey)
_, err = sm2.State(&sc2, protocol.KeyOption(candKey[:]))
_, err = sm2.State(&sc2, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
act2 := action.NewPutPollResult(1, 1, sc2)
elp = bd.SetGasLimit(uint64(100000)).
Expand Down Expand Up @@ -415,7 +416,7 @@ func TestProtocol_Validate(t *testing.T) {
require.NoError(err)
require.NoError(p3.CreateGenesisStates(ctx3, sm3))
var sc3 state.CandidateList
_, err = sm3.State(&sc3, protocol.KeyOption(candKey[:]))
_, err = sm3.State(&sc3, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
sc3 = append(sc3, &state.Candidate{"1", big.NewInt(10), "2", nil})
sc3 = append(sc3, &state.Candidate{"1", big.NewInt(10), "2", nil})
Expand Down Expand Up @@ -447,7 +448,7 @@ func TestProtocol_Validate(t *testing.T) {
require.NoError(err)
require.NoError(p4.CreateGenesisStates(ctx4, sm4))
var sc4 state.CandidateList
_, err = sm4.State(&sc4, protocol.KeyOption(candKey[:]))
_, err = sm4.State(&sc4, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
sc4 = append(sc4, &state.Candidate{"1", big.NewInt(10), "2", nil})
act4 := action.NewPutPollResult(1, 1, sc4)
Expand Down Expand Up @@ -478,7 +479,7 @@ func TestProtocol_Validate(t *testing.T) {
require.NoError(err)
require.NoError(p5.CreateGenesisStates(ctx5, sm5))
var sc5 state.CandidateList
_, err = sm5.State(&sc5, protocol.KeyOption(candKey[:]))
_, err = sm5.State(&sc5, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
sc5[0].Votes = big.NewInt(10)
act5 := action.NewPutPollResult(1, 1, sc5)
Expand Down Expand Up @@ -509,7 +510,7 @@ func TestProtocol_Validate(t *testing.T) {
require.NoError(err)
require.NoError(p6.CreateGenesisStates(ctx6, sm6))
var sc6 state.CandidateList
_, err = sm6.State(&sc6, protocol.KeyOption(candKey[:]))
_, err = sm6.State(&sc6, protocol.KeyOption(candKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
require.NoError(err)
act6 := action.NewPutPollResult(1, 1, sc6)
bd6 := &action.EnvelopeBuilder{}
Expand Down Expand Up @@ -550,7 +551,7 @@ func TestDelegatesByEpoch(t *testing.T) {
BlacklistInfos: blackListMap,
IntensityRate: 0.1,
}
require.NoError(setKickoutBlackList(sm, blackList))
require.NoError(setNextEpochBlacklist(sm, blackList))

delegates, err := p.DelegatesByEpoch(ctx, 2)
require.NoError(err)
Expand All @@ -567,7 +568,7 @@ func TestDelegatesByEpoch(t *testing.T) {
BlacklistInfos: blackListMap2,
IntensityRate: 0.1,
}
require.NoError(setKickoutBlackList(sm, blackList2))
require.NoError(setNextEpochBlacklist(sm, blackList2))
delegates2, err := p.DelegatesByEpoch(ctx, 2)
require.NoError(err)
require.Equal(2, len(delegates2))
Expand All @@ -584,7 +585,7 @@ func TestDelegatesByEpoch(t *testing.T) {
BlacklistInfos: blackListMap3,
IntensityRate: 0.1,
}
require.NoError(setKickoutBlackList(sm, blackList3))
require.NoError(setNextEpochBlacklist(sm, blackList3))

delegates3, err := p.DelegatesByEpoch(ctx, 2)
require.NoError(err)
Expand All @@ -594,7 +595,8 @@ func TestDelegatesByEpoch(t *testing.T) {
require.Equal(identityset.Address(4).String(), delegates3[1].Address)

// 4: shift kickout list and Delegates()
require.NoError(shiftKickoutList(sm))
_, err = shiftKickoutList(sm)
require.NoError(err)
delegates4, err := p.DelegatesByEpoch(ctx, 2)
require.NoError(err)
require.Equal(len(delegates4), len(delegates3))
Expand Down
48 changes: 27 additions & 21 deletions action/protocol/poll/util.go
Expand Up @@ -182,17 +182,17 @@ func setCandidates(
return err
}
nextKey := candidatesutil.ConstructKey(candidatesutil.NxtCandidateKey)
_, err := sm.PutState(&candidates, protocol.KeyOption(nextKey[:]))
_, err := sm.PutState(&candidates, protocol.KeyOption(nextKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
return err
}

// setKickoutBlackList sets the blacklist for kick-out with next key
func setKickoutBlackList(
// setNextEpochBlacklist sets the blacklist for kick-out with next key
func setNextEpochBlacklist(
sm protocol.StateManager,
blackList *vote.Blacklist,
) error {
blackListKey := candidatesutil.ConstructKey(candidatesutil.NxtKickoutKey)
_, err := sm.PutState(blackList, protocol.KeyOption(blackListKey[:]))
_, err := sm.PutState(blackList, protocol.KeyOption(blackListKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
return err
}

Expand All @@ -202,52 +202,58 @@ func setUnproductiveDelegates(
upd *vote.UnproductiveDelegate,
) error {
updKey := candidatesutil.ConstructKey(candidatesutil.UnproductiveDelegateKey)
_, err := sm.PutState(upd, protocol.KeyOption(updKey[:]))
_, err := sm.PutState(upd, protocol.KeyOption(updKey[:]), protocol.NamespaceOption(protocol.SystemNamespace))
return err
}

// shiftCandidates updates current data with next data of candidate list
func shiftCandidates(sm protocol.StateManager) error {
func shiftCandidates(sm protocol.StateManager) (uint64, error) {
zap.L().Debug("Shift candidatelist from next key to current key")
var next state.CandidateList
var err error
var stateHeight, putStateHeight uint64
nextKey := candidatesutil.ConstructKey(candidatesutil.NxtCandidateKey)
_, err := sm.State(&next, protocol.KeyOption(nextKey[:]))
if err != nil {
return errors.Wrap(
if stateHeight, err = sm.State(&next, protocol.KeyOption(nextKey[:]), protocol.NamespaceOption(protocol.SystemNamespace)); err != nil {
return 0, errors.Wrap(
err,
"failed to read next blacklist when shifting to current blacklist",
)
}
curKey := candidatesutil.ConstructKey(candidatesutil.CurCandidateKey)
_, err = sm.PutState(&next, protocol.KeyOption(curKey[:]))
if err != nil {
return errors.Wrap(
if putStateHeight, err = sm.PutState(&next, protocol.KeyOption(curKey[:]), protocol.NamespaceOption(protocol.SystemNamespace)); err != nil {
return 0, errors.Wrap(
err,
"failed to write current blacklist when shifting from next blacklist to current blacklist",
)
}
return nil
if stateHeight != putStateHeight {
return 0, errors.Wrap(ErrInconsistentHeight, "failed to shift candidates")
}
return stateHeight, nil
}

// shiftKickoutList updates current data with next data of kickout list
func shiftKickoutList(sm protocol.StateManager) error {
func shiftKickoutList(sm protocol.StateManager) (uint64, error) {
zap.L().Debug("Shift kickoutList from next key to current key")
var err error
var stateHeight, putStateHeight uint64
next := &vote.Blacklist{}
nextKey := candidatesutil.ConstructKey(candidatesutil.NxtKickoutKey)
_, err := sm.State(next, protocol.KeyOption(nextKey[:]))
if err != nil {
return errors.Wrap(
if stateHeight, err = sm.State(next, protocol.KeyOption(nextKey[:]), protocol.NamespaceOption(protocol.SystemNamespace)); err != nil {
return 0, errors.Wrap(
err,
"failed to read next blacklist when shifting to current blacklist",
)
}
curKey := candidatesutil.ConstructKey(candidatesutil.CurKickoutKey)
_, err = sm.PutState(next, protocol.KeyOption(curKey[:]))
if err != nil {
return errors.Wrap(
if putStateHeight, err = sm.PutState(next, protocol.KeyOption(curKey[:]), protocol.NamespaceOption(protocol.SystemNamespace)); err != nil {
return 0, errors.Wrap(
err,
"failed to write current blacklist when shifting from next blacklist to current blacklist",
)
}
return nil
if stateHeight != putStateHeight {
return 0, errors.Wrap(ErrInconsistentHeight, "failed to shift candidates")
}
return stateHeight, nil
}