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

Fix gocycle in engine.go #430

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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: 1 addition & 1 deletion bcs/ledger/xledger/state/meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ func (t *Meta) LoadGasPrice() (*protos.GasPrice, error) {
return nil, ErrProposalParamsIsNegativeNumber
}
// To be compatible with the old version v3.3
// If GasPrice configuration is missing or value euqals 0, support a default value
// If GasPrice configuration is missing or value equals 0, support a default value
if cpuRate == 0 && memRate == 0 && diskRate == 0 && xfeeRate == 0 {
gasPrice = &protos.GasPrice{
CpuRate: 1000,
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.14

require (
github.com/ChainSafe/go-schnorrkel v0.0.0-20200626160457-b38283118816 // indirect
github.com/agiledragon/gomonkey/v2 v2.9.0
github.com/aws/aws-sdk-go v1.32.4
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/dgraph-io/badger/v3 v3.2103.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrd
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/agiledragon/gomonkey/v2 v2.9.0 h1:PDiKKybR596O6FHW+RVSG0Z7uGCBNbmbUXh3uCNQ7Hc=
github.com/agiledragon/gomonkey/v2 v2.9.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
github.com/alecthomas/jsonschema v0.0.0-20190122210438-a6952de1bbe6/go.mod h1:qpebaTNSsyUn5rPSJMsfqEtDw71TTggXM6stUDI16HA=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
Expand Down
191 changes: 118 additions & 73 deletions kernel/engines/xuperos/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package xuperos

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"

Expand All @@ -14,6 +14,7 @@ import (
engconf "github.com/xuperchain/xupercore/kernel/engines/xuperos/config"
xnet "github.com/xuperchain/xupercore/kernel/engines/xuperos/net"
"github.com/xuperchain/xupercore/kernel/engines/xuperos/parachain"
"github.com/xuperchain/xupercore/kernel/ledger"
"github.com/xuperchain/xupercore/lib/logs"
"github.com/xuperchain/xupercore/lib/storage/kvdb"
"github.com/xuperchain/xupercore/lib/timer"
Expand Down Expand Up @@ -162,111 +163,155 @@ func (t *Engine) GetChains() []string {
return t.chainM.GetChains()
}

// 从本地存储加载链
/* 从本地存储加载链
Default directories:
data
└── blockchain
├── <root chain>
├── <para chain 1>
│ ...
└── <para chain n>
*/
func (t *Engine) loadChains() error {
envCfg := t.engCtx.EnvCfg
dataDir := envCfg.GenDataAbsPath(envCfg.ChainDir)
ChainsDir := envCfg.GenDataAbsPath(envCfg.ChainDir)
zhugelianglongming marked this conversation as resolved.
Show resolved Hide resolved
t.log.Trace("start load chains from blockchain data dir", "dir", ChainsDir)

t.log.Trace("start load chain from blockchain data dir", "dir", dataDir)
dir, err := ioutil.ReadDir(dataDir)
// 优先加载主链
if err := t.loadRootChain(ChainsDir); err != nil {
return err
}

// 加载平行链
paraChainCnt, err := t.loadParaChains(ChainsDir)
if err != nil {
t.log.Error("read blockchain data dir failed", "error", err, "dir", dataDir)
return fmt.Errorf("read blockchain data dir failed")
return err
}

chainCnt := 0
t.log.Trace("load chain from data dir succeeded", "chainCnt", 1+paraChainCnt)
return nil
}

// loadRootChain loads root chain from given directory
func (t *Engine) loadRootChain(chainsDir string) error {
rootChain := t.engCtx.EngCfg.RootChain
chainDir := filepath.Join(chainsDir, rootChain)

// 优先加载主链
for _, fInfo := range dir {
if !fInfo.IsDir() || fInfo.Name() != rootChain {
continue
}
chainDir := filepath.Join(dataDir, fInfo.Name())
t.log.Trace("start load chain", "chain", fInfo.Name(), "dir", chainDir)
chain, err := LoadChain(t.engCtx, fInfo.Name())
if err != nil {
t.log.Error("load chain from data dir failed", "error", err, "dir", chainDir)
return err
}
t.log.Trace("load chain from data dir succ", "chain", fInfo.Name())

// 记录链实例
t.chainM.Put(fInfo.Name(), chain)

// 启动异步任务worker
if fInfo.Name() == rootChain {
aw, err := asyncworker.NewAsyncWorkerImpl(fInfo.Name(), t, chain.ctx.State.GetLDB())
if err != nil {
t.log.Error("create asyncworker error", "bcName", rootChain, "err", err)
return err
}
chain.ctx.Asyncworker = aw
err = chain.CreateParaChain()
if err != nil {
t.log.Error("create parachain mgmt error", "bcName", rootChain, "err", err)
return fmt.Errorf("create parachain error")
}
if err = aw.Start(); err != nil {
return err
}
}
// check root chain dir
if fi, err := os.Stat(chainDir); err != nil {
return err
} else if !fi.IsDir() {
return fmt.Errorf("load root chain fail: %s is not dir", chainDir)
}

t.log.Trace("load chain succeeded", "chain", fInfo.Name(), "dir", chainDir)
chainCnt++
// load chain
t.log.Trace("start load chain", "chain", rootChain, "dir", chainDir)
chain, err := LoadChain(t.engCtx, rootChain)
if err != nil {
t.log.Error("load chain from data dir failed", "error", err, "dir", chainDir)
return err
}
t.chainM.Put(rootChain, chain)
t.log.Trace("load chain from data dir succ", "chain", rootChain)

// start async worker
aw, err := asyncworker.NewAsyncWorkerImpl(rootChain, t, chain.ctx.State.GetLDB())
if err != nil {
t.log.Error("create asyncworker error", "bcName", rootChain, "err", err)
return err
}
chain.ctx.Asyncworker = aw
err = chain.CreateParaChain()
if err != nil {
t.log.Error("create parachain mgmt error", "bcName", rootChain, "err", err)
return fmt.Errorf("create parachain error")
}
if err = aw.Start(); err != nil {
return err
}

t.log.Trace("load chain succeeded", "chain", rootChain, "dir", chainDir)
return nil
}

// loadParaChains loads non-root chains from given directory
// Returns:
//
// int: loaded ParaChain count
func (t *Engine) loadParaChains(chainsDir string) (int, error) {
zhugelianglongming marked this conversation as resolved.
Show resolved Hide resolved
// prepare root chain reader
// root链必须存在
rootChain := t.engCtx.EngCfg.RootChain
rootChainHandle, err := t.chainM.Get(rootChain)
if err != nil {
t.log.Error("root chain not exist, please create it first", "rootChain", rootChain)
return fmt.Errorf("root chain not exist")
return 0, fmt.Errorf("root chain not exist")
}
rootChainReader, err := rootChainHandle.Context().State.GetTipXMSnapshotReader()
if err != nil {
t.log.Error("root chain get tip reader failed", "err", err.Error())
return err
return 0, err
}
// 加载平行链
for _, fInfo := range dir {

// load ParaChains
dirs, err := os.ReadDir(chainsDir)
if err != nil {
t.log.Error("read blockchain data dir failed", "error", err, "dir", chainsDir)
return 0, fmt.Errorf("read blockchain data dir failed")
}

chainCnt := 0
for _, fInfo := range dirs {
if !fInfo.IsDir() || fInfo.Name() == rootChain {
continue
}

// 通过主链的平行链账本状态,确认是否可以加载该平行链
group, err := parachain.GetParaChainGroup(rootChainReader, fInfo.Name())
loaded, err := t.tryLoadParaChain(chainsDir, fInfo.Name(), rootChainReader)
if err != nil {
t.log.Error("get para chain group failed", "chain", fInfo.Name(), "err", err.Error())
if !kvdb.ErrNotFound(err) {
continue
}
return err
return 0, err
}

if !group.IsParaChainEnable() {
t.log.Debug("para chain stopped", "chain", fInfo.Name())
continue
if loaded {
chainCnt++
}
}
return chainCnt, nil
}

chainDir := filepath.Join(dataDir, fInfo.Name())
t.log.Trace("start load chain", "chain", fInfo.Name(), "dir", chainDir)
chain, err := LoadChain(t.engCtx, fInfo.Name())
if err != nil {
t.log.Error("load chain from data dir failed", "error", err, "dir", chainDir)
// 平行链加载失败时可以忽略直接跳过运行
continue
// tryLoadParaChain try to load a given ParaChain from given directory, checked by root chain info.
// Returns:
//
// bool: true when a ParaChain is loaded
func (t *Engine) tryLoadParaChain(chainsDir, chainName string,
rootChainReader ledger.XMSnapshotReader) (bool, error) {

// 通过主链的平行链账本状态,确认是否可以加载该平行链
group, err := parachain.GetParaChainGroup(rootChainReader, chainName)
if err != nil {
t.log.Error("get para chain group failed", "chain", chainName, "err", err.Error())
if !kvdb.ErrNotFound(err) {
return false, nil
}
t.log.Trace("load chain from data dir succ", "chain", fInfo.Name())
return false, err
}

// 记录链实例
t.chainM.Put(fInfo.Name(), chain)
if !group.IsParaChainEnable() {
t.log.Debug("para chain stopped", "chain", chainName)
return false, nil
}

t.log.Trace("load chain succeeded", "chain", fInfo.Name(), "dir", chainDir)
chainCnt++
chainDir := filepath.Join(chainsDir, chainName)
t.log.Trace("start load chain", "chain", chainName, "dir", chainDir)
chain, err := LoadChain(t.engCtx, chainName)
if err != nil {
t.log.Error("load chain from data dir failed", "error", err, "dir", chainDir)
// 平行链加载失败时可以忽略直接跳过运行
return false, nil
}
// 记录链实例
t.chainM.Put(chainName, chain)

t.log.Trace("load chain from data dir succeeded", "chainCnt", chainCnt)
return nil
t.log.Trace("load chain succeeded", "chain", chainName, "dir", chainDir)
return true, nil
}

func (t *Engine) createEngCtx(envCfg *xconf.EnvConf) (*common.EngineCtx, error) {
Expand Down
Loading