Commit 91b38090 authored by mdj33's avatar mdj33 Committed by vipwzw

self consens ok

parent 70f755a0
......@@ -1012,9 +1012,11 @@ func GetSelfConsStagesCmd() *cobra.Command {
func stageOneInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
height, _ := cmd.Flags().GetInt64("height")
params := types.Int64{Data: height}
var res pt.SelfConsensStage
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetSelfConsOneStage", nil, &res)
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetSelfConsOneStage", params, &res)
ctx.Run()
}
......
......@@ -318,18 +318,16 @@ func updateCommitAddrs(stat *pt.ParacrossHeightStatus, nodes map[string]struct{}
func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
var stage *pt.SelfConsensStage
if types.IsPara() && types.IsDappFork(a.height, pt.ParaX, pt.ForkParaSelfConsStages) {
stages, err := getSelfConsensStages(a.db)
if types.IsPara() && cfg.IsDappFork(a.height, pt.ParaX, pt.ForkParaSelfConsStages) {
//分叉之后,key不存在,自共识没配置也认为不支持自共识
isSelfConsOn, err := isSelfConsOn(a.db, commit.Status.Height)
if err != nil {
return nil, err
}
stage = getSelfConsOneStage(a.height, stages)
if stage.Enable == pt.ParaConfigNo {
return nil, pt.ErrConsensClosed
if !isSelfConsOn {
clog.Debug("paracross.Commit self consens off", "height", commit.Status.Height)
return &types.Receipt{Ty: types.ExecOk}, nil
}
}
err := checkCommitInfo(cfg, commit)
if err != nil {
......@@ -469,7 +467,12 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
if commit.Status.Height > titleStatus.Height+1 {
saveTitleHeight(a.db, calcTitleHeightKey(commit.Status.Title, commit.Status.Height), stat)
//平行链由主链共识无缝切换,即接收第一个收到的高度,可以不从0开始
if !a.isAllowConsensJump(stat, titleStatus, stage) {
allow, err := a.isAllowConsensJump(stat, titleStatus)
if err != nil {
clog.Error("paracross.Commit allowJump", "err", err)
return nil, err
}
if !allow {
return receipt, nil
}
}
......@@ -719,13 +722,21 @@ func (a *action) isAllowMainConsensJump(commit *pt.ParacrossHeightStatus, titleS
//平行链自共识无缝切换条件:1,平行链没有共识过,2:commit高度是大于自共识分叉高度且上一次共识的主链高度小于自共识分叉高度,保证只运行一次,
// 1. 分叉之前,开启过共识的平行链需要从1跳跃,没开启过的将使用新版本,从0开始发送,不用考虑从1跳跃的问题
// 2. 分叉之后,只有stage.blockHeight== commit.height,也就是stage起始高度时候允许跳跃
func (a *action) isAllowParaConsensJump(commit *pt.ParacrossHeightStatus, titleStatus *pt.ParacrossStatus, stage *pt.SelfConsensStage) bool {
if types.IsDappFork(a.height, pt.ParaX, pt.ForkParaSelfConsStages) {
return stage.BlockHeight == commit.Height
func (a *action) isAllowParaConsensJump(commit *pt.ParacrossHeightStatus, titleStatus *pt.ParacrossStatus) (bool, error) {
cfg := a.api.GetConfig()
if cfg.IsDappFork(a.height, pt.ParaX, pt.ForkParaSelfConsStages) {
stage, err := getSelfConsOneStage(a.db, commit.Height)
if err != nil && errors.Cause(err) != pt.ErrKeyNotExist {
return false, err
}
if stage == nil {
return false, nil
}
return stage.BlockHeight == commit.Height, nil
}
//兼容分叉之前从1跳跃场景
return titleStatus.Height == -1
return titleStatus.Height == -1, nil
}
func (a *action) isAllowConsensJump(commit *pt.ParacrossCommitAction, titleStatus *pt.ParacrossStatus) (bool, error) {
......@@ -733,7 +744,7 @@ func (a *action) isAllowConsensJump(commit *pt.ParacrossCommitAction, titleStatu
if cfg.IsPara() {
return a.isAllowParaConsensJump(commit, titleStatus)
}
return a.isAllowMainConsensJump(commit, titleStatus)
return a.isAllowMainConsensJump(commit, titleStatus), nil
}
......@@ -951,7 +962,7 @@ func (a *action) Miner(miner *pt.ParacrossMinerAction) (*types.Receipt, error) {
if types.IsDappFork(a.height, pt.ParaX, pt.ForkParaSelfConsStages) {
var err error
isSelfConsensOn, err = isSelfConsOn(a.db, miner.Status.Height)
if err != nil {
if err != nil && errors.Cause(err) != pt.ErrKeyNotExist {
clog.Error("paracross miner getConsensus ", "height", miner.Status.Height, "err", err)
return nil, err
}
......
......@@ -421,12 +421,10 @@ func (p *Paracross) Query_GetSelfConsStages(in *types.ReqNil) (types.Message, er
//Query_GetSelfConsOneStage get self consensus one stage
func (p *Paracross) Query_GetSelfConsOneStage(in *types.Int64) (types.Message, error) {
stages, err := getSelfConsensStages(p.GetStateDB())
stage, err := getSelfConsOneStage(p.GetStateDB(), in.Data)
if err != nil {
return nil, errors.Cause(err)
return nil, err
}
stage := getSelfConsOneStage(in.Data, stages)
return stage, nil
}
......
......@@ -116,9 +116,15 @@ func sortStages(stages *pt.SelfConsensStages, new *pt.SelfConsensStage) {
func updateStages(db dbm.KV, stage *pt.SelfConsensStage) (*types.Receipt, error) {
stages, err := getSelfConsensStages(db)
if err != nil {
if err != nil && errors.Cause(err) != pt.ErrKeyNotExist {
return nil, err
}
if stages == nil {
stages = &pt.SelfConsensStages{}
stages.Items = append(stages.Items, stage)
return makeStageGroupReceipt(nil, stages), nil
}
var old pt.SelfConsensStages
err = deepCopy(&old, stages)
if err != nil {
......@@ -140,43 +146,50 @@ func selfConsensInitStage() *types.Receipt {
return makeStageGroupReceipt(nil, stages)
}
func getSelfConsOneStage(height int64, stages *pt.SelfConsensStages) *pt.SelfConsensStage {
func getSelfConsOneStage(db dbm.KV, height int64) (*pt.SelfConsensStage, error) {
stages, err := getSelfConsensStages(db)
if err != nil {
return nil, err
}
for i := len(stages.Items) - 1; i >= 0; i-- {
if height >= stages.Items[i].BlockHeight {
return stages.Items[i]
return stages.Items[i], nil
}
}
return &pt.SelfConsensStage{Enable: pt.ParaConfigNo}
return nil, errors.Wrapf(pt.ErrKeyNotExist, "SelfConsStage not found to height:%d", height)
}
func isSelfConsOn(db dbm.KV, height int64) (bool, error) {
stages, err := getSelfConsensStages(db)
if err != nil && errors.Cause(err) != pt.ErrKeyNotExist {
stage, err := getSelfConsOneStage(db, height)
if err != nil {
return false, err
}
if stages != nil {
stage := getSelfConsOneStage(height, stages)
return stage.Enable == pt.ParaConfigYes, nil
}
return false, nil
return stage.Enable == pt.ParaConfigYes, nil
}
func (a *action) checkValidStage(config *pt.SelfConsensStage) error {
//0. 设置高度必须大于fork高度
if !types.IsDappFork(config.BlockHeight, pt.ParaX, pt.ForkParaSelfConsStages) {
return errors.Wrapf(types.ErrNotAllow, "checkValidStage config height:%d less than fork height", config.BlockHeight)
}
//1. 设置高度必须大于当前区块高度
if config.BlockHeight <= a.height {
return errors.Wrapf(pt.ErrHeightHasPast, "checkValidStage config height:%d less than block height:%d", config.BlockHeight, a.height)
}
//2. 如果已经设置到stages中,简单起见,就不能更改了,应该也不会有很大影响
stages, err := getSelfConsensStages(a.db)
if err != nil {
if err != nil && errors.Cause(err) != pt.ErrKeyNotExist {
return errors.Wrapf(err, "checkValidStage get stages")
}
stageMap := getSelfConsStagesMap(stages.Items)
if _, exist := stageMap[config.BlockHeight]; exist {
return errors.Wrapf(err, "checkValidStage config height:%d existed", config.BlockHeight)
if stages != nil {
stageMap := getSelfConsStagesMap(stages.Items)
if _, exist := stageMap[config.BlockHeight]; exist {
return errors.Wrapf(err, "checkValidStage config height:%d existed", config.BlockHeight)
}
}
//3. enable check
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment