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

add chain_config system contract, add upMaxBlockSize and upGasPrice func #460

Closed
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
2 changes: 2 additions & 0 deletions bcs/ledger/xledger/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,15 @@ 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"
// Irreversible block height & slide window
IrreversibleBlockHeightKey = "IrreversibleBlockHeight"
IrreversibleSlideWindowKey = "IrreversibleSlideWindow"
GasPriceKey = "GasPrice"
OldGasPriceKey = "OldGasPrice"
GroupChainContractKey = "GroupChainContract"
)

Expand Down
79 changes: 61 additions & 18 deletions bcs/ledger/xledger/state/meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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()
Expand All @@ -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")
Expand All @@ -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
}
4 changes: 2 additions & 2 deletions bcs/ledger/xledger/state/meta/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,15 @@ 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)
}
err = metaHadler.UpdateNewAccountResourceAmount(500, batch)
if err != nil {
t.Fatal(err)
}
err = metaHadler.UpdateMaxBlockSize(64, batch)
err = metaHadler.UpdateMaxBlockSize(metaHadler.GetMaxBlockSize(), 64, batch)
if err != nil {
t.Fatal(err)
}
Expand Down
65 changes: 63 additions & 2 deletions bcs/ledger/xledger/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions kernel/contract/proposal/utils/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const (
TimerTaskKernelContract = "$timer_task"
TDPOSKernelContract = "$tdpos"
XPOSKernelContract = "$xpos"
ChainConfigKernelContract = "$chainConfig"
)

// Govern Token Balance
Expand Down
16 changes: 13 additions & 3 deletions kernel/contract/proposal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 17 additions & 0 deletions kernel/engines/xuperos/agent/rely.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions kernel/engines/xuperos/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
3 changes: 3 additions & 0 deletions kernel/engines/xuperos/chain_config/base/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package base

type UpdateCfgManger interface{}
48 changes: 48 additions & 0 deletions kernel/engines/xuperos/chain_config/context.go
Original file line number Diff line number Diff line change
@@ -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
}
7 changes: 7 additions & 0 deletions kernel/engines/xuperos/chain_config/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package chain_config

import "errors"

var (
NewChainConfigCtxErr = errors.New("new updateConfig ctx faild because param error")
)
Loading
Loading