Skip to content

Commit

Permalink
qbase增加支持validator变更功能
Browse files Browse the repository at this point in the history
  • Loading branch information
TokenxyWZY committed Mar 19, 2019
1 parent 3dc7d98 commit 78dbb1a
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 0 deletions.
10 changes: 10 additions & 0 deletions baseabci/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/QOSGroup/qbase/store"
"github.com/QOSGroup/qbase/txs"
"github.com/QOSGroup/qbase/types"
"github.com/QOSGroup/qbase/validator"

go_amino "github.com/tendermint/go-amino"
abci "github.com/tendermint/tendermint/abci/types"
Expand Down Expand Up @@ -92,6 +93,7 @@ func NewBaseApp(name string, logger log.Logger, db dbm.DB, registerCodecFunc fun

app.registerQcpMapper()
app.RegisterMapper(consensus.NewConsensusMapper(cdc))
app.RegisterMapper(validator.NewValidatorMapper())
return app
}

Expand Down Expand Up @@ -367,6 +369,9 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
res = app.beginBlocker(app.deliverState.ctx, req)
}

valMapper := validator.GetValidatorMapper(app.deliverState.ctx)
valMapper.SetLastBlockProposer(req.Header.GetProposerAddress())
valMapper.ClearValidatorUpdateSet()
// set the signed validators for addition to context in deliverTx
app.voteInfos = req.LastCommitInfo.GetVotes()

Expand Down Expand Up @@ -841,6 +846,11 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc
res = app.endBlocker(app.deliverState.ctx, req)
}

valMapper := validator.GetValidatorMapper(app.deliverState.ctx)
if b := valMapper.IsEnableValidatorUpdated(); b {
res.ValidatorUpdates = valMapper.GetValidatorUpdateSet()
}

return
}

Expand Down
16 changes: 16 additions & 0 deletions validator/key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package validator

const (
ValidatorMapperName = "_base_validator_"
)

var (
//EnableValidatorUpdatedKey 是否启用更新validator特性,默认关闭
EnableValidatorUpdatedKey = []byte("_enable_validator_updated_")

//ValidatorUpdateSetKey 保存本块中validator变化结果
ValidatorUpdateSetKey = []byte("_validator_update_set_")

//LastBlockProposerKey 上一块验证人
LastBlockProposerKey = []byte("_last_block_proposer_")
)
67 changes: 67 additions & 0 deletions validator/validator_mapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package validator

import (
"github.com/QOSGroup/qbase/context"
"github.com/QOSGroup/qbase/mapper"
"github.com/QOSGroup/qbase/types"
abci "github.com/tendermint/tendermint/abci/types"
)

type ValidatorMapper struct {
*mapper.BaseMapper
}

func (mapper *ValidatorMapper) ClearValidatorUpdateSet() {
mapper.Del(ValidatorUpdateSetKey)
}

func (mapper *ValidatorMapper) GetValidatorUpdateSet() (update []abci.ValidatorUpdate) {
mapper.Get(ValidatorUpdateSetKey, &update)
return
}

func (mapper *ValidatorMapper) SetValidatorUpdateSet(update []abci.ValidatorUpdate) {
mapper.Set(ValidatorUpdateSetKey, update)
}

func (mapper *ValidatorMapper) SetLastBlockProposer(address types.Address) {
mapper.Set(LastBlockProposerKey, address)
}

func (mapper *ValidatorMapper) GetLastBlockProposer() (address types.Address, exsits bool) {
exsits = mapper.Get(LastBlockProposerKey, &address)
return
}

func (mapper *ValidatorMapper) IsEnableValidatorUpdated() bool {
if v, exsits := mapper.GetBool(EnableValidatorUpdatedKey); exsits {
return v
}
return false
}

func (mapper *ValidatorMapper) EnableValidatorUpdated() {
mapper.Set(EnableValidatorUpdatedKey, true)
}

func (mapper *ValidatorMapper) DisableValidatorUpdated() {
mapper.Set(EnableValidatorUpdatedKey, false)
}

var _ mapper.IMapper = (*ValidatorMapper)(nil)

func NewValidatorMapper() *ValidatorMapper {
var validatorMapper = ValidatorMapper{}
validatorMapper.BaseMapper = mapper.NewBaseMapper(nil, ValidatorMapperName)
return &validatorMapper
}

func GetValidatorMapper(ctx context.Context) *ValidatorMapper {
return ctx.Mapper(ValidatorMapperName).(*ValidatorMapper)
}

func (mapper *ValidatorMapper) Copy() mapper.IMapper {
validatorMapper := &ValidatorMapper{}
validatorMapper.BaseMapper = mapper.BaseMapper.Copy()
return validatorMapper
}
80 changes: 80 additions & 0 deletions validator/validator_mapper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package validator

import (
"testing"

"github.com/QOSGroup/qbase/context"
"github.com/QOSGroup/qbase/mapper"
"github.com/QOSGroup/qbase/store"
"github.com/QOSGroup/qbase/types"
"github.com/stretchr/testify/require"
go_amino "github.com/tendermint/go-amino"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
)

func defaultContext(key store.StoreKey, mapperMap map[string]mapper.IMapper) context.Context {
db := dbm.NewMemDB()
cms := store.NewCommitMultiStore(db)
cms.MountStoreWithDB(key, store.StoreTypeIAVL, db)
cms.LoadLatestVersion()
ctx := context.NewContext(cms, abci.Header{}, false, log.NewNopLogger(), mapperMap)
return ctx
}

func getValidatorMapper() *ValidatorMapper {
cdc := go_amino.NewCodec()

seedMapper := NewValidatorMapper()
seedMapper.SetCodec(cdc)

mapperMap := make(map[string]mapper.IMapper)
mapperMap[seedMapper.MapperName()] = seedMapper

ctx := defaultContext(seedMapper.GetStoreKey(), mapperMap)
return GetValidatorMapper(ctx)
}

func TestValidatorMapper(t *testing.T) {

valMapper := getValidatorMapper()
b := valMapper.IsEnableValidatorUpdated()
require.Equal(t, false, b)

valMapper.EnableValidatorUpdated()

b = valMapper.IsEnableValidatorUpdated()
require.Equal(t, true, b)

valMapper.DisableValidatorUpdated()

b = valMapper.IsEnableValidatorUpdated()
require.Equal(t, false, b)

s := valMapper.GetValidatorUpdateSet()
require.Equal(t, 0, len(s))

s = []abci.ValidatorUpdate{
{}, {},
}

valMapper.SetValidatorUpdateSet(s)
s = valMapper.GetValidatorUpdateSet()
require.Equal(t, 2, len(s))

valMapper.ClearValidatorUpdateSet()

s = valMapper.GetValidatorUpdateSet()
require.Equal(t, 0, len(s))

addr, _ := valMapper.GetLastBlockProposer()
require.Equal(t, true, addr.Empty())

addr = types.Address{12, 20, 32}
valMapper.SetLastBlockProposer(addr)

addr, _ = valMapper.GetLastBlockProposer()
require.Equal(t, false, addr.Empty())

}

0 comments on commit 78dbb1a

Please sign in to comment.