From acc72b48ac825427a009c263fcc1f86354102bb8 Mon Sep 17 00:00:00 2001 From: laertes Date: Wed, 24 Jan 2024 18:05:31 +0800 Subject: [PATCH] add chain_config system contract, add upMaxBlockSize and upGasPrice func --- bcs/ledger/xledger/ledger/ledger.go | 2 + bcs/ledger/xledger/state/meta/meta.go | 79 ++++++++++++---- bcs/ledger/xledger/state/meta/meta_test.go | 13 +-- bcs/ledger/xledger/state/state.go | 65 ++++++++++++- kernel/contract/proposal/utils/types.go | 1 + kernel/contract/proposal/utils/utils.go | 16 +++- kernel/engines/xuperos/agent/rely.go | 17 ++++ kernel/engines/xuperos/chain.go | 6 ++ .../xuperos/chain_config/base/interface.go | 3 + .../engines/xuperos/chain_config/context.go | 48 ++++++++++ kernel/engines/xuperos/chain_config/types.go | 7 ++ .../xuperos/chain_config/update_config.go | 91 +++++++++++++++++++ .../chain_config/update_config_manager.go | 25 +++++ kernel/engines/xuperos/common/interface.go | 2 + 14 files changed, 346 insertions(+), 29 deletions(-) create mode 100644 kernel/engines/xuperos/chain_config/base/interface.go create mode 100644 kernel/engines/xuperos/chain_config/context.go create mode 100644 kernel/engines/xuperos/chain_config/types.go create mode 100644 kernel/engines/xuperos/chain_config/update_config.go create mode 100644 kernel/engines/xuperos/chain_config/update_config_manager.go diff --git a/bcs/ledger/xledger/ledger/ledger.go b/bcs/ledger/xledger/ledger/ledger.go index 94466e7c..f467c29d 100644 --- a/bcs/ledger/xledger/ledger/ledger.go +++ b/bcs/ledger/xledger/ledger/ledger.go @@ -59,6 +59,7 @@ const ( BlockCacheSize = 1000 // block counts in lru cache TxCacheSize = 100000 // tx counts in lru cache MaxBlockSizeKey = "MaxBlockSize" + OldBlockSizeKey = "OldMaxBlockSize" ReservedContractsKey = "ReservedContracts" ForbiddenContractKey = "ForbiddenContract" NewAccountResourceAmountKey = "NewAccountResourceAmount" @@ -66,6 +67,7 @@ const ( IrreversibleBlockHeightKey = "IrreversibleBlockHeight" IrreversibleSlideWindowKey = "IrreversibleSlideWindow" GasPriceKey = "GasPrice" + OldGasPriceKey = "OldGasPrice" GroupChainContractKey = "GroupChainContract" ) diff --git a/bcs/ledger/xledger/state/meta/meta.go b/bcs/ledger/xledger/state/meta/meta.go index d0a9a5ba..7b137d54 100644 --- a/bcs/ledger/xledger/state/meta/meta.go +++ b/bcs/ledger/xledger/state/meta/meta.go @@ -176,25 +176,34 @@ func (t *Meta) MaxTxSizePerBlock() (int, error) { return int(float64(maxBlkSize) * TxSizePercent), nil } -func (t *Meta) UpdateMaxBlockSize(maxBlockSize int64, batch kvdb.Batch) error { - if maxBlockSize <= 0 { +func (t *Meta) UpdateMaxBlockSize(oldMaxBlockSize, newMaxBlockSize int64, batch kvdb.Batch) error { + if newMaxBlockSize <= 0 { return ErrProposalParamsIsNotPositiveNumber } tmpMeta := &pb.UtxoMeta{} newMeta := proto.Clone(tmpMeta).(*pb.UtxoMeta) - newMeta.MaxBlockSize = maxBlockSize - maxBlockSizeBuf, pbErr := proto.Marshal(newMeta) - if pbErr != nil { - t.log.Warn("failed to marshal pb meta") - return pbErr + + // 记录old max block size + err := putMaxBlockSizeInBatch(batch, newMeta, []byte(pb.MetaTablePrefix+ledger.OldBlockSizeKey), oldMaxBlockSize) + if err != nil { + t.log.Warn("batch write err: ", err) + return err } - err := batch.Put([]byte(pb.MetaTablePrefix+ledger.MaxBlockSizeKey), maxBlockSizeBuf) - if err == nil { - t.log.Info("Update maxBlockSize succeed") + // 记录new max block size + err = putMaxBlockSizeInBatch(batch, newMeta, []byte(pb.MetaTablePrefix+ledger.MaxBlockSizeKey), newMaxBlockSize) + if err != nil { + t.log.Warn("batch write err: ", err) + return err } + err = batch.Write() + if err != nil { + t.log.Warn("batch write err: ", err) + return err + } + t.MutexMeta.Lock() defer t.MutexMeta.Unlock() - t.MetaTmp.MaxBlockSize = maxBlockSize + t.MetaTmp.MaxBlockSize = newMaxBlockSize return err } @@ -492,7 +501,7 @@ func (t *Meta) LoadGasPrice() (*protos.GasPrice, error) { } // UpdateGasPrice update gasPrice parameters -func (t *Meta) UpdateGasPrice(nextGasPrice *protos.GasPrice, batch kvdb.Batch) error { +func (t *Meta) UpdateGasPrice(oldGasPrice, nextGasPrice *protos.GasPrice, batch kvdb.Batch) error { // check if the parameters are valid cpuRate := nextGasPrice.GetCpuRate() memRate := nextGasPrice.GetMemRate() @@ -503,14 +512,21 @@ func (t *Meta) UpdateGasPrice(nextGasPrice *protos.GasPrice, batch kvdb.Batch) e } tmpMeta := &pb.UtxoMeta{} newMeta := proto.Clone(tmpMeta).(*pb.UtxoMeta) - newMeta.GasPrice = nextGasPrice - gasPriceBuf, pbErr := proto.Marshal(newMeta) - if pbErr != nil { - t.log.Warn("failed to marshal pb meta") - return pbErr + + // 先保存上一轮数据 + err := putGasPriceInBatch(batch, newMeta, []byte(pb.MetaTablePrefix+ledger.OldGasPriceKey), oldGasPrice) + if err != nil { + return err + } + // 保存下一轮数据 + err = putGasPriceInBatch(batch, newMeta, []byte(pb.MetaTablePrefix+ledger.GasPriceKey), nextGasPrice) + if err != nil { + return err } - err := batch.Put([]byte(pb.MetaTablePrefix+ledger.GasPriceKey), gasPriceBuf) + + err = batch.Write() if err != nil { + t.log.Warn("batch write err: ", err) return err } t.log.Info("Update gas price succeed") @@ -519,3 +535,30 @@ func (t *Meta) UpdateGasPrice(nextGasPrice *protos.GasPrice, batch kvdb.Batch) e t.MetaTmp.GasPrice = nextGasPrice return nil } + +func putGasPriceInBatch(batch kvdb.Batch, tmpMeta *pb.UtxoMeta, key []byte, gasPrice *protos.GasPrice) error { + tmpMeta.GasPrice = gasPrice + gasPriceBuf, pbErr := proto.Marshal(tmpMeta) + if pbErr != nil { + return pbErr + } + err := batch.Put(key, gasPriceBuf) + if err != nil { + return err + } + return nil +} + +func putMaxBlockSizeInBatch(batch kvdb.Batch, tmpMeta *pb.UtxoMeta, key []byte, maxBlockSize int64) error { + tmpMeta.MaxBlockSize = maxBlockSize + maxBlockSizeBuf, pbErr := proto.Marshal(tmpMeta) + if pbErr != nil { + return pbErr + } + + err := batch.Put(key, maxBlockSizeBuf) + if err != nil { + return err + } + return nil +} diff --git a/bcs/ledger/xledger/state/meta/meta_test.go b/bcs/ledger/xledger/state/meta/meta_test.go index 6c0eadd9..2c416963 100644 --- a/bcs/ledger/xledger/state/meta/meta_test.go +++ b/bcs/ledger/xledger/state/meta/meta_test.go @@ -1,15 +1,16 @@ package meta import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + "github.com/xuperchain/xupercore/bcs/ledger/xledger/def" "github.com/xuperchain/xupercore/kernel/mock" "github.com/xuperchain/xupercore/lib/logs" "github.com/xuperchain/xupercore/lib/storage/kvdb" "github.com/xuperchain/xupercore/protos" - "io/ioutil" - "os" - "path/filepath" - "testing" ledger_pkg "github.com/xuperchain/xupercore/bcs/ledger/xledger/ledger" "github.com/xuperchain/xupercore/bcs/ledger/xledger/state/context" @@ -190,7 +191,7 @@ func TestMetaGetFunc(t *testing.T) { DiskRate: 1, XfeeRate: 1, } - err = metaHadler.UpdateGasPrice(gasPrice, batch) + err = metaHadler.UpdateGasPrice(metaHadler.GetGasPrice(), gasPrice, batch) if err != nil { t.Fatal(err) } @@ -198,7 +199,7 @@ func TestMetaGetFunc(t *testing.T) { if err != nil { t.Fatal(err) } - err = metaHadler.UpdateMaxBlockSize(64, batch) + err = metaHadler.UpdateMaxBlockSize(metaHadler.GetMaxBlockSize(), 64, batch) if err != nil { t.Fatal(err) } diff --git a/bcs/ledger/xledger/state/state.go b/bcs/ledger/xledger/state/state.go index 07518fb9..34c2f01f 100644 --- a/bcs/ledger/xledger/state/state.go +++ b/bcs/ledger/xledger/state/state.go @@ -12,7 +12,6 @@ import ( "time" "github.com/golang/protobuf/proto" - "github.com/xuperchain/xupercore/bcs/ledger/xledger/def" "github.com/xuperchain/xupercore/bcs/ledger/xledger/ledger" "github.com/xuperchain/xupercore/bcs/ledger/xledger/state/context" @@ -28,6 +27,7 @@ import ( governToken "github.com/xuperchain/xupercore/kernel/contract/proposal/govern_token" "github.com/xuperchain/xupercore/kernel/contract/proposal/propose" timerTask "github.com/xuperchain/xupercore/kernel/contract/proposal/timer" + proposeUtils "github.com/xuperchain/xupercore/kernel/contract/proposal/utils" kledger "github.com/xuperchain/xupercore/kernel/ledger" aclBase "github.com/xuperchain/xupercore/kernel/permission/acl/base" "github.com/xuperchain/xupercore/lib/cache" @@ -1011,7 +1011,14 @@ func (t *State) undoTxInternal(tx *pb.Transaction, batch kvdb.Batch) error { t.log.Warn("xmodel.UndoTx failed", "err", err) return ErrRWSetInvalid } - + // Timer 交易回滚 + if tx.Autogen { + outPutsExt := tx.GetTxOutputsExt() + err = t.rollBackTimerTx(outPutsExt, batch) + if err != nil { + return err + } + } for _, txInput := range tx.TxInputs { addr := txInput.FromAddr txid := txInput.RefTxid @@ -1504,6 +1511,60 @@ func (t *State) GetContractDesc(contractName string) (*protos.WasmCodeDesc, erro } return valDesc, err } +func (t *State) UpdateGasPrice(oldGasPrice, nextGasPrice *protos.GasPrice, batch kvdb.Batch) error { + return t.meta.UpdateGasPrice(oldGasPrice, nextGasPrice, batch) +} + +func (t *State) UpdateMaxBlockSize(oldMaxBlockSize, maxBlockSize int64, batch kvdb.Batch) error { + return t.meta.UpdateMaxBlockSize(oldMaxBlockSize, maxBlockSize, batch) +} + +func (t *State) rollBackTimerTx(outPutsExt []*protos.TxOutputExt, batch kvdb.Batch) error { + for _, output := range outPutsExt { + if output.Bucket == proposeUtils.GetProposalBucket() { + proposalStr := output.Value + proposal, err := proposeUtils.Parse(string(proposalStr)) + if err != nil { + return err + } + switch proposal.Trigger.Method { + case proposeUtils.GetUpdateMaxBlockSizeMethod(): + return t.rollbackUpdateMaxBlocsSize(batch) + case proposeUtils.GetUpdateGasPriceMethod(): + return t.rollbackUpdateGasPrice(batch) + } + } + } + return nil +} + +func (t *State) rollbackUpdateGasPrice(batch kvdb.Batch) error { + oldGasPrice := t.meta.GetGasPrice() + gasPriceBuf, finderr := t.meta.MetaTable.Get([]byte(ledger.OldGasPriceKey)) + if finderr == nil { + utxoMeta := &pb.UtxoMeta{} + err := proto.Unmarshal(gasPriceBuf, utxoMeta) + if err != nil { + return err + } + return t.meta.UpdateGasPrice(oldGasPrice, utxoMeta.GetGasPrice(), batch) + } + return finderr +} + +func (t *State) rollbackUpdateMaxBlocsSize(batch kvdb.Batch) error { + oldMaxBlockSize := t.meta.GetMaxBlockSize() + maxBlockSizeBuf, findErr := t.meta.MetaTable.Get([]byte(ledger.OldBlockSizeKey)) + if findErr == nil { + utxoMeta := &pb.UtxoMeta{} + err := proto.Unmarshal(maxBlockSizeBuf, utxoMeta) + if err != nil { + return err + } + return t.meta.UpdateMaxBlockSize(oldMaxBlockSize, utxoMeta.GetMaxBlockSize(), batch) + } + return findErr +} func (t *State) HasUnconfirmTx() bool { return t.tx.Mempool.GetTxCounnt() != 0 diff --git a/kernel/contract/proposal/utils/types.go b/kernel/contract/proposal/utils/types.go index 7441c462..51e6c2b9 100644 --- a/kernel/contract/proposal/utils/types.go +++ b/kernel/contract/proposal/utils/types.go @@ -23,6 +23,7 @@ const ( TimerTaskKernelContract = "$timer_task" TDPOSKernelContract = "$tdpos" XPOSKernelContract = "$xpos" + ChainConfigKernelContract = "$chainConfig" ) // Govern Token Balance diff --git a/kernel/contract/proposal/utils/utils.go b/kernel/contract/proposal/utils/utils.go index 51d23791..10ff5759 100644 --- a/kernel/contract/proposal/utils/utils.go +++ b/kernel/contract/proposal/utils/utils.go @@ -17,11 +17,21 @@ const ( separator = "_" prefixEnd = "~" - proposalBucket = "proposal" - proposalIDKey = "id" - proposalLockKey = "lock" + proposalBucket = "proposal" + proposalIDKey = "id" + proposalLockKey = "lock" + updateGasPriceMethod = "updateGasPrice" + updateMaxBlockSizeMethod = "updateMaxBlockSize" ) +func GetUpdateGasPriceMethod() string { + return updateGasPriceMethod +} + +func GetUpdateMaxBlockSizeMethod() string { + return updateMaxBlockSizeMethod +} + // GetGovernTokenBucket return the govern token bucket name func GetGovernTokenBucket() string { return governTokenBucket diff --git a/kernel/engines/xuperos/agent/rely.go b/kernel/engines/xuperos/agent/rely.go index b2fde5e0..526e36f1 100644 --- a/kernel/engines/xuperos/agent/rely.go +++ b/kernel/engines/xuperos/agent/rely.go @@ -18,6 +18,8 @@ import ( governToken "github.com/xuperchain/xupercore/kernel/contract/proposal/govern_token" "github.com/xuperchain/xupercore/kernel/contract/proposal/propose" timerTask "github.com/xuperchain/xupercore/kernel/contract/proposal/timer" + chainConfig "github.com/xuperchain/xupercore/kernel/engines/xuperos/chain_config" + chainConfigBase "github.com/xuperchain/xupercore/kernel/engines/xuperos/chain_config/base" "github.com/xuperchain/xupercore/kernel/engines/xuperos/common" "github.com/xuperchain/xupercore/kernel/engines/xuperos/xevidence" xevidenceInter "github.com/xuperchain/xupercore/kernel/engines/xuperos/xevidence/base" @@ -241,6 +243,21 @@ func (t *ChainRelyAgentImpl) CreateXToken() (xtokenInter.XTokenManager, error) { return mgr, err } +func (t *ChainRelyAgentImpl) CreateUpdateConfig() (chainConfigBase.UpdateCfgManger, error) { + ctx := t.chain.Context() + legAgent := NewLedgerAgent(ctx) + ctx.Ledger = legAgent.chainCtx.Ledger + UpCfgCtx, err := chainConfig.NewChainConfigCtx(ctx) + if err != nil { + return nil, err + } + mgr, err := chainConfig.NewChainConfigManager(UpCfgCtx) + if err != nil { + return nil, err + } + return mgr, nil +} + func (t *ChainRelyAgentImpl) CreateXEvidence() (xevidenceInter.XEvidenceManager, error) { ctx := t.chain.Context() xctx, err := xevidence.NewXEvidenceCtx(ctx) diff --git a/kernel/engines/xuperos/chain.go b/kernel/engines/xuperos/chain.go index 897f98be..6f0e1f2b 100644 --- a/kernel/engines/xuperos/chain.go +++ b/kernel/engines/xuperos/chain.go @@ -458,6 +458,12 @@ func (t *Chain) initChainCtx() error { if err != nil { return err } + // update_config + _, err = t.relyAgent.CreateUpdateConfig() + if err != nil { + return err + } + t.log.Trace("create UpdateConfig succ", "bcName", t.ctx.BCName) // 11.xevidence创建,存证系统合约 _, err = t.relyAgent.CreateXEvidence() diff --git a/kernel/engines/xuperos/chain_config/base/interface.go b/kernel/engines/xuperos/chain_config/base/interface.go new file mode 100644 index 00000000..0a2f26cd --- /dev/null +++ b/kernel/engines/xuperos/chain_config/base/interface.go @@ -0,0 +1,3 @@ +package base + +type UpdateCfgManger interface{} diff --git a/kernel/engines/xuperos/chain_config/context.go b/kernel/engines/xuperos/chain_config/context.go new file mode 100644 index 00000000..ef8e0263 --- /dev/null +++ b/kernel/engines/xuperos/chain_config/context.go @@ -0,0 +1,48 @@ +package chain_config + +import ( + "fmt" + + "github.com/xuperchain/xupercore/kernel/common/xcontext" + "github.com/xuperchain/xupercore/kernel/contract" + "github.com/xuperchain/xupercore/kernel/contract/proposal/utils" + "github.com/xuperchain/xupercore/kernel/engines/xuperos/common" + "github.com/xuperchain/xupercore/kernel/ledger" + "github.com/xuperchain/xupercore/lib/logs" + "github.com/xuperchain/xupercore/lib/timer" + "github.com/xuperchain/xupercore/protos" +) + +type LedgerRely interface { + GetTipXMSnapshotReader() (ledger.XMSnapshotReader, error) +} + +type ChainConfigCtx struct { + xcontext.BaseCtx + BcName string + Contract contract.Manager + ChainCtx *common.ChainCtx + OldGasPrice *protos.GasPrice + OldMaxBlockSize int64 +} + +func NewChainConfigCtx(chainCtx *common.ChainCtx) (*ChainConfigCtx, error) { + if chainCtx.BCName == "" || chainCtx.Contract == nil { + return nil, NewChainConfigCtxErr + } + + log, err := logs.NewLogger("", utils.ChainConfigKernelContract) + if err != nil { + return nil, fmt.Errorf("new updateConfig ctx faild because new logger error. err: %v", err) + } + meta := chainCtx.State.GetMeta() + ctx := new(ChainConfigCtx) + ctx.XLog = log + ctx.Timer = timer.NewXTimer() + ctx.BcName = chainCtx.BCName + ctx.Contract = chainCtx.Contract + ctx.ChainCtx = chainCtx + ctx.OldGasPrice = meta.GetGasPrice() + ctx.OldMaxBlockSize = meta.GetMaxBlockSize() + return ctx, nil +} diff --git a/kernel/engines/xuperos/chain_config/types.go b/kernel/engines/xuperos/chain_config/types.go new file mode 100644 index 00000000..511737b7 --- /dev/null +++ b/kernel/engines/xuperos/chain_config/types.go @@ -0,0 +1,7 @@ +package chain_config + +import "errors" + +var ( + NewChainConfigCtxErr = errors.New("new updateConfig ctx faild because param error") +) diff --git a/kernel/engines/xuperos/chain_config/update_config.go b/kernel/engines/xuperos/chain_config/update_config.go new file mode 100644 index 00000000..3c6ada73 --- /dev/null +++ b/kernel/engines/xuperos/chain_config/update_config.go @@ -0,0 +1,91 @@ +package chain_config + +import ( + "encoding/json" + "fmt" + + "github.com/xuperchain/xupercore/kernel/contract" + "github.com/xuperchain/xupercore/kernel/contract/proposal/utils" + "github.com/xuperchain/xupercore/protos" +) + +type KernMethod struct { + BcName string + Context *ChainConfigCtx +} + +func NewKernMethod(ctx *ChainConfigCtx) *KernMethod { + t := &KernMethod{ + BcName: ctx.BcName, + Context: ctx, + } + return t +} + +func (k *KernMethod) updateGasPrice(contractCtx contract.KContext) (*contract.Response, error) { + ctxArgs := contractCtx.Args() + args := make(map[string]interface{}) + err := json.Unmarshal(ctxArgs["args"], &args) + if err != nil { + return nil, fmt.Errorf("unmarshal ctxArgs err: %v", err) + } + var nextGasPrice protos.GasPrice + gasPriceMap, ok := args["gas_price"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("gasPriceMap err, gasPriceMap %v", args["gasprice"]) + } + gasPriceByte, err := json.Marshal(&gasPriceMap) + if err != nil { + return nil, fmt.Errorf("gasPriceByte err: %v", err) + } + err = json.Unmarshal(gasPriceByte, &nextGasPrice) + if err != nil { + return nil, fmt.Errorf("unmarshal gasPriceByte err: %v", err) + } + // 调用方法 + if k.Context.ChainCtx == nil { + // 单测时 chainctx == nil + return &contract.Response{ + Status: utils.StatusOK, + Message: "success", + Body: nil, + }, nil + } + batch := k.Context.ChainCtx.State.NewBatch() + err = k.Context.ChainCtx.State.UpdateGasPrice(k.Context.OldGasPrice, &nextGasPrice, batch) + if err != nil { + return nil, fmt.Errorf("update gas price err: %v", err) + } + return &contract.Response{ + Status: utils.StatusOK, + Message: "success", + Body: nil, + }, nil +} + +func (k *KernMethod) updateMaxBlockSize(contractCtx contract.KContext) (*contract.Response, error) { + ctxArgs := contractCtx.Args() + args := make(map[string]int64) + err := json.Unmarshal(ctxArgs["args"], &args) + if err != nil { + return nil, fmt.Errorf("unmarshal ctxArgs err: %v", err) + } + if k.Context.ChainCtx == nil { + // 单测时 chainctx == nil + return &contract.Response{ + Status: utils.StatusOK, + Message: "success", + Body: nil, + }, nil + } + batch := k.Context.ChainCtx.State.NewBatch() + err = k.Context.ChainCtx.State.UpdateMaxBlockSize(k.Context.OldMaxBlockSize, args["maxBlockSize"], batch) + if err != nil { + return nil, fmt.Errorf("update max block size err: %v", err) + } + return &contract.Response{ + Status: utils.StatusOK, + Message: "success", + Body: nil, + }, nil +} diff --git a/kernel/engines/xuperos/chain_config/update_config_manager.go b/kernel/engines/xuperos/chain_config/update_config_manager.go new file mode 100644 index 00000000..3d12f8ee --- /dev/null +++ b/kernel/engines/xuperos/chain_config/update_config_manager.go @@ -0,0 +1,25 @@ +package chain_config + +import ( + "fmt" + + "github.com/xuperchain/xupercore/kernel/contract/proposal/utils" +) + +type Manager struct { + Ctx *ChainConfigCtx +} + +func NewChainConfigManager(ctx *ChainConfigCtx) (*Manager, error) { + if ctx == nil || ctx.Contract == nil || ctx.BcName == "" { + return nil, fmt.Errorf("update config ctx set error") + } + t := NewKernMethod(ctx) + register := ctx.Contract.GetKernRegistry() + register.RegisterKernMethod(utils.ChainConfigKernelContract, utils.GetUpdateGasPriceMethod(), t.updateGasPrice) + register.RegisterKernMethod(utils.ChainConfigKernelContract, utils.GetUpdateMaxBlockSizeMethod(), t.updateMaxBlockSize) + mg := &Manager{ + Ctx: ctx, + } + return mg, nil +} diff --git a/kernel/engines/xuperos/common/interface.go b/kernel/engines/xuperos/common/interface.go index 7e1dcb06..5767014f 100644 --- a/kernel/engines/xuperos/common/interface.go +++ b/kernel/engines/xuperos/common/interface.go @@ -12,6 +12,7 @@ import ( "github.com/xuperchain/xupercore/kernel/contract/proposal/propose" timerTask "github.com/xuperchain/xupercore/kernel/contract/proposal/timer" "github.com/xuperchain/xupercore/kernel/engines" + chainConfigBase "github.com/xuperchain/xupercore/kernel/engines/xuperos/chain_config/base" "github.com/xuperchain/xupercore/kernel/engines/xuperos/xtoken/base" kledger "github.com/xuperchain/xupercore/kernel/ledger" "github.com/xuperchain/xupercore/kernel/network" @@ -65,6 +66,7 @@ type ChainRelyAgent interface { CreateProposal() (propose.ProposeManager, error) CreateTimerTask() (timerTask.TimerManager, error) CreateXToken() (base.XTokenManager, error) + CreateUpdateConfig() (chainConfigBase.UpdateCfgManger, error) CreateXEvidence() (xevidenceInter.XEvidenceManager, error) }