Skip to content

Commit

Permalink
add chain_config system contract, add upMaxBlockSize and upGasPrice f…
Browse files Browse the repository at this point in the history
…unc (#461)
  • Loading branch information
superlitian authored Mar 21, 2024
1 parent d92f6fa commit b2d87a2
Show file tree
Hide file tree
Showing 14 changed files with 341 additions and 25 deletions.
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

0 comments on commit b2d87a2

Please sign in to comment.