Commit 724b07c3 authored by 陈德海's avatar 陈德海

change gob to types to get size

parent 271da6d4
......@@ -73,7 +73,7 @@ poolCacheSize=10240
[mempool.sub.score]
poolCacheSize=10240
timeParam=1 #时间占价格比例
priceConstant=3 #手续费相对于时间的一个的常量,排队时手续费高1e3的分数~=快1h的分数
priceConstant=10 #手续费相对于时间的一个的常量,排队时手续费高1e3的分数~=快1h的分数
pricePower=1 #常量比例
[mempool.sub.price]
......
package price
import (
"bytes"
"encoding/gob"
"github.com/33cn/chain33/common/skiplist"
"github.com/33cn/chain33/system/mempool"
"github.com/33cn/chain33/types"
......@@ -28,14 +25,8 @@ func NewQueue(subcfg subConfig) *Queue {
}
func (cache *Queue) newSkipValue(item *mempool.Item) (*skiplist.SkipValue, error) {
//tx := item.value
buf := bytes.NewBuffer(nil)
enc := gob.NewEncoder(buf)
err := enc.Encode(item.Value)
if err != nil {
return nil, err
}
size := len(buf.Bytes())
buf := types.Encode(item.Value)
size := len(buf)
return &skiplist.SkipValue{Score: item.Value.Fee / int64(size), Value: item}, nil
}
......@@ -139,11 +130,11 @@ func (cache *Queue) GetProperFee() int64 {
return cache.subConfig.ProperFee
}
i := 0
cache.Walk(0, func(tx *mempool.Item) bool {
cache.txList.Walk(func(tx interface{}) bool {
if i == 100 {
return false
}
sumFee += tx.Value.Fee
sumFee += tx.(*mempool.Item).Value.Fee
i++
return true
})
......
package score
import (
"bytes"
"encoding/gob"
"time"
"github.com/33cn/chain33/common/skiplist"
"github.com/33cn/chain33/system/mempool"
"github.com/33cn/chain33/types"
"time"
)
var mempoolDupResendInterval int64 = 600 // mempool内交易过期时间,10分钟
// Queue 分数队列模式(分数=常量a*手续费/交易字节数-常量b*时间*定量c,按分数排队,高的优先,常量a,b和定量c可配置)
// Queue 分数队列模式(分数=定量a*常量b*手续费/交易字节数-常量c*时间,按分数排队,高的优先,定量a和常量b,c可配置)
type Queue struct {
txMap map[string]*skiplist.SkipValue
txList *skiplist.SkipList
......@@ -29,14 +26,8 @@ func NewQueue(subcfg subConfig) *Queue {
}
func (cache *Queue) newSkipValue(item *mempool.Item) (*skiplist.SkipValue, error) {
//tx := item.value
buf := bytes.NewBuffer(nil)
enc := gob.NewEncoder(buf)
err := enc.Encode(item.Value)
if err != nil {
return nil, err
}
size := len(buf.Bytes())
buf := types.Encode(item.Value)
size := len(buf)
return &skiplist.SkipValue{Score: cache.subConfig.PriceConstant*(item.Value.Fee/int64(size))*
cache.subConfig.PricePower - cache.subConfig.TimeParam*item.EnterTime, Value: item}, nil
}
......@@ -133,17 +124,16 @@ func (cache *Queue) GetProperFee() int64 {
return cache.subConfig.ProperFee
}
i := 0
cache.Walk(0, func(tx *mempool.Item) bool {
cache.txList.WalkS(func(node interface{}) bool {
if i == 100 {
return false
}
//这里的int64(500)是一般交易的大小
sumScore += cache.subConfig.PriceConstant*tx.Value.Fee*
cache.subConfig.PricePower*int64(500) - cache.subConfig.TimeParam*tx.EnterTime
sumScore += node.(*skiplist.SkipValue).Score
i++
return true
})
properFee = (sumScore/int64(cache.Size()) + cache.subConfig.TimeParam*time.Now().Unix()) /
(cache.subConfig.PriceConstant * cache.subConfig.PricePower * int64(500))
//这里的int64(250)是一般交易的大小
properFee = (sumScore/int64(i) + cache.subConfig.TimeParam*time.Now().Unix()) * int64(250) /
(cache.subConfig.PriceConstant * cache.subConfig.PricePower)
return properFee
}
......@@ -158,11 +158,15 @@ func TestGetProperFee(t *testing.T) {
cache.Push(item3)
cache.Push(item4)
cache.GetProperFee()
score3 := item3.Priority*cache.subConfig.PriceConstant*cache.subConfig.PricePower*int64(500) -
buf3 := types.Encode(item3.Value)
size3 := len(buf3)
buf4 := types.Encode(item4.Value)
size4 := len(buf4)
score3 := item3.Value.Fee*cache.subConfig.PriceConstant*cache.subConfig.PricePower/int64(size3) -
item3.EnterTime*cache.subConfig.TimeParam
score4 := item4.Priority*cache.subConfig.PriceConstant*cache.subConfig.PricePower*int64(500) -
score4 := item4.Value.Fee*cache.subConfig.PriceConstant*cache.subConfig.PricePower/int64(size4) -
item4.EnterTime*cache.subConfig.TimeParam
properFee := ((score3+score4)/2 + time.Now().Unix()*cache.subConfig.TimeParam) /
(cache.subConfig.PriceConstant * cache.subConfig.PricePower * int64(500))
assert.Equal(t, properFee, cache.GetProperFee())
properFee := ((score3+score4)/2 + time.Now().Unix()*cache.subConfig.TimeParam) * int64(250) /
(cache.subConfig.PriceConstant * cache.subConfig.PricePower)
assert.Equal(t, int64(1), properFee/cache.GetProperFee())
}
......@@ -75,7 +75,7 @@ poolCacheSize=10240
[mempool.sub.score]
poolCacheSize=10240
timeParam=1 #时间占价格比例
priceConstant=3 #手续费相对于时间的一个的常量,排队时手续费高1e3的分数~=快1h的分数
priceConstant=10 #手续费相对于时间的一个的常量,排队时手续费高1e3的分数~=快1h的分数
pricePower=1 #常量比例
[mempool.sub.price]
......
......@@ -18,6 +18,7 @@ PKG_LIST := `go list ./... | grep -v "vendor" | grep -v "mocks"`
PKG_LIST_VET := `go list ./... | grep -v "vendor" | grep -v "common/crypto/sha3" | grep -v "common/log/log15"`
PKG_LIST_INEFFASSIGN= `go list -f {{.Dir}} ./... | grep -v "vendor" | grep -v "common/crypto/sha3" | grep -v "common/log/log15" | grep -v "common/ed25519"`
PKG_LIST_Q := `go list ./... | grep -v "vendor" | grep -v "mocks"`
PKG_LIST_GOSEC := `go list ./... | grep -v "vendor" | grep -v "mocks" | grep -v "cmd" | grep -v "types" | grep -v "commands" | grep -v "log15" | grep -v "ed25519" | grep -v "crypto"`
BUILD_FLAGS = -ldflags "-X github.com/33cn/chain33/common/version.GitCommit=`git rev-parse --short=8 HEAD`"
MKPATH=$(abspath $(lastword $(MAKEFILE_LIST)))
MKDIR=$(dir $(MKPATH))
......@@ -88,7 +89,7 @@ build_ci: depends ## Build the binary file for CI
@go build $(BUILD_FLAGS) -v -o $(APP) $(SRC)
@cp cmd/chain33/chain33.toml build/
linter: vet ineffassign ## Use gometalinter check code, ignore some unserious warning
linter: vet ineffassign gosec ## Use gometalinter check code, ignore some unserious warning
@./golinter.sh "filter"
@find . -name '*.sh' -not -path "./vendor/*" | xargs shellcheck
......@@ -96,6 +97,9 @@ linter_test: ## Use gometalinter check code, for local test
@./golinter.sh "test" "${p}"
@find . -name '*.sh' -not -path "./vendor/*" | xargs shellcheck
gosec:
@gosec -quiet=true -exclude=G107,G402,G302 ${PKG_LIST_GOSEC}
race: ## Run data race detector
@go test -race -short $(PKG_LIST)
......
......@@ -193,14 +193,20 @@ func (acc *DB) transferReceipt(fromkv, tokv []*types.KeyValue, receiptFrom, rece
func (acc *DB) SaveAccount(acc1 *types.Account) {
set := acc.GetKVSet(acc1)
for i := 0; i < len(set); i++ {
acc.db.Set(set[i].GetKey(), set[i].Value)
err := acc.db.Set(set[i].GetKey(), set[i].Value)
if err != nil {
panic(err)
}
}
}
//SaveKVSet 保存Key Value set
func (acc *DB) SaveKVSet(set []*types.KeyValue) {
for i := 0; i < len(set); i++ {
acc.db.Set(set[i].GetKey(), set[i].Value)
err := acc.db.Set(set[i].GetKey(), set[i].Value)
if err != nil {
panic(err)
}
}
}
......
......@@ -37,7 +37,10 @@ func (acc *DB) LoadExecAccountQueue(api client.QueueProtocolAPI, addr, execaddr
func (acc *DB) SaveExecAccount(execaddr string, acc1 *types.Account) {
set := acc.GetExecKVSet(execaddr, acc1)
for i := 0; i < len(set); i++ {
acc.db.Set(set[i].GetKey(), set[i].Value)
err := acc.db.Set(set[i].GetKey(), set[i].Value)
if err != nil {
panic(err)
}
}
}
......
......@@ -9,17 +9,16 @@ clone_folder: c:\gopath\src\github.com\33cn\chain33
environment:
GOPATH: c:\gopath
DEPTESTBYPASS501: 1
GOVERSION: 1.9
GOVERSION: 1.9.7
#init:
# - git config --global core.autocrlf input
# Build
install:
# Install the specific Go version.
- rmdir c:\go /s /q
- appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.msi
- appveyor DownloadFile https://dl.google.com/go/go%GOVERSION%.windows-amd64.msi
- msiexec /i go%GOVERSION%.windows-amd64.msi /q
# - choco install bzr
- set Path=c:\go\bin;c:\gopath\bin;C:\Program Files (x86)\Bazaar\;C:\Program Files\Mercurial\%Path%
......
......@@ -453,16 +453,16 @@ func (_m *QueueProtocolAPI) GetMempool() (*types.ReplyTxList, error) {
return r0, r1
}
// GetProperFee provides a mock function with given fields:
func (_m *QueueProtocolAPI) GetProperFee() (*types.ReplyProperFee, error) {
// GetNetInfo provides a mock function with given fields:
func (_m *QueueProtocolAPI) GetNetInfo() (*types.NodeNetInfo, error) {
ret := _m.Called()
var r0 *types.ReplyProperFee
if rf, ok := ret.Get(0).(func() *types.ReplyProperFee); ok {
var r0 *types.NodeNetInfo
if rf, ok := ret.Get(0).(func() *types.NodeNetInfo); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ReplyProperFee)
r0 = ret.Get(0).(*types.NodeNetInfo)
}
}
......@@ -476,16 +476,16 @@ func (_m *QueueProtocolAPI) GetProperFee() (*types.ReplyProperFee, error) {
return r0, r1
}
// GetNetInfo provides a mock function with given fields:
func (_m *QueueProtocolAPI) GetNetInfo() (*types.NodeNetInfo, error) {
// GetProperFee provides a mock function with given fields:
func (_m *QueueProtocolAPI) GetProperFee() (*types.ReplyProperFee, error) {
ret := _m.Called()
var r0 *types.NodeNetInfo
if rf, ok := ret.Get(0).(func() *types.NodeNetInfo); ok {
var r0 *types.ReplyProperFee
if rf, ok := ret.Get(0).(func() *types.ReplyProperFee); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.NodeNetInfo)
r0 = ret.Get(0).(*types.ReplyProperFee)
}
}
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package commands
import (
"fmt"
"github.com/33cn/chain33/cmd/tools/strategy"
"github.com/33cn/chain33/cmd/tools/types"
"github.com/spf13/cobra"
)
//GenDappCmd advance cmd
func GenDappCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "gendapp",
Short: "Auto generate dapp basic code",
Run: genDapp,
}
addGenDappFlag(cmd)
return cmd
}
func addGenDappFlag(cmd *cobra.Command) {
cmd.Flags().StringP("name", "n", "", "dapp name")
cmd.MarkFlagRequired("name")
cmd.Flags().StringP("proto", "p", "", "dapp protobuf file path")
cmd.MarkFlagRequired("proto")
cmd.Flags().StringP("output", "o", "", "go package for output (default github.com/33cn/plugin/plugin/dapp/)")
}
func genDapp(cmd *cobra.Command, args []string) {
dappName, _ := cmd.Flags().GetString("name")
outDir, _ := cmd.Flags().GetString("output")
propFile, _ := cmd.Flags().GetString("proto")
s := strategy.New(types.KeyGenDapp)
if s == nil {
fmt.Println(types.KeyGenDapp, "Not support")
return
}
s.SetParam(types.KeyExecutorName, dappName)
s.SetParam(types.KeyDappOutDir, outDir)
s.SetParam(types.KeyProtobufFile, propFile)
s.Run()
}
syntax = "proto3";
package accounts;
package types;
message DemoAction {
oneof value {
DemoCreate create = 1;
DemoRun play = 2;
DemoClose show = 3;
DemoHello hello = 1;
DemoEcho echo = 2;
}
int32 ty = 6;
int32 ty = 3;
}
message DemoCreate {
[ consensus - ticket ] string name = 1;
}
message DemoHello {}
message DemoRun {
string name = 1;
message DemoEcho {
string data = 1;
}
message DemoClose {
string name = 1;
}
\ No newline at end of file
package executor
import (
"github.com/33cn/chain33/plugin/dapp/${EXECNAME}/ptypes"
ptypes "github.com/33cn/plugin/plugin/dapp/${EXECNAME}/types"
"github.com/33cn/chain33/types"
)
......@@ -4,7 +4,7 @@ import (
"fmt"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/plugin/dapp/${CLASSNAME}/ptypes"
ptypes "github.com/33cn/chain33/plugin/dapp/${CLASSNAME}/types"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
)
......
package unfreeze
import (
"github.com/33cn/chain33/plugin/dapp/${CLASSNAME}/commands"
"github.com/33cn/chain33/plugin/dapp/${CLASSNAME}/ptypes"
"github.com/33cn/chain33/plugin/dapp/${CLASSNAME}/executor"
"github.com/33cn/plugin/plugin/dapp/${CLASSNAME}/commands"
"github.com/33cn/plugin/plugin/dapp/${CLASSNAME}/types"
"github.com/33cn/plugin/plugin/dapp/${CLASSNAME}/executor"
"github.com/33cn/chain33/pluginmgr"
)
func init() {
pluginmgr.Register(&pluginmgr.PluginBase{
Name: ptyoes.PackageName,
Name: types.PackageName,
ExecName: executor.GetName(),
Exec: executor.Init,
Cmd: commands.Cmd,
......
#!/bin/sh
protoc --go_out=plugins=grpc:../ptypes ./*.proto
protoc --go_out=plugins=grpc:../types ./*.proto
package rpc
import (
ptypes "github.com/33cn/chain33/plugin/dapp/${EXECNAME}/types"
ptypes "github.com/33cn/plugin/plugin/dapp/${EXECNAME}/types"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
)
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package base
var (
//CodeFileManager 类型文件
CodeFileManager = map[string][]ICodeFile{}
)
// ICodeFile code file interface
type ICodeFile interface {
GetCodeType() string
GetDirName() string
GetFiles() map[string]string //key:filename, val:file content
GetReplaceTags() []string
}
//RegisterCodeFile regeister code file
func RegisterCodeFile(filer ICodeFile) {
codeType := filer.GetCodeType()
fileArr := CodeFileManager[codeType]
fileArr = append(fileArr, filer)
CodeFileManager[codeType] = fileArr
}
// CodeFile 基础类
type CodeFile struct {
}
//GetCodeType get cody type
func (CodeFile) GetCodeType() string {
return ""
}
//GetDirName get directory name
func (CodeFile) GetDirName() string {
return ""
}
//GetFiles get files
func (CodeFile) GetFiles() map[string]string {
return nil
}
//GetReplaceTags get replace tags
func (CodeFile) GetReplaceTags() []string {
return nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package base
// DappCodeFile dapp code source
type DappCodeFile struct {
CodeFile
}
// GetCodeType get code type
func (DappCodeFile) GetCodeType() string {
return "dapp"
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gencode
const (
//ProtoFileAppendService proto文件service
ProtoFileAppendService = `
service ${EXECNAME} {
}`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cmd
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
)
func init() {
base.RegisterCodeFile(cmdCodeFile{})
}
type cmdCodeFile struct {
base.DappCodeFile
}
func (cmdCodeFile) GetDirName() string {
return "cmd"
}
func (cmdCodeFile) GetFiles() map[string]string {
return map[string]string{
buildShellName: buildShellContent,
makeFIleName: makeFileContent,
}
}
var (
buildShellName = "build.sh"
buildShellContent = `#!/bin/sh
# 官方ci集成脚本
strpwd=$(pwd)
strcmd=${strpwd##*dapp/}
strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
#FLAG=$2
mkdir -p "${OUT_DIR}"
cp ./build/* "${OUT_DIR}"
`
makeFIleName = "Makefile"
makeFileContent = `all:
chmod +x ./build.sh
./build.sh $(OUT) $(FLAG)
`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package commands
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
"github.com/33cn/chain33/cmd/tools/types"
)
func init() {
base.RegisterCodeFile(commandsCodeFile{})
}
type commandsCodeFile struct {
base.DappCodeFile
}
func (c commandsCodeFile) GetDirName() string {
return "commands"
}
func (c commandsCodeFile) GetFiles() map[string]string {
return map[string]string{
commandsFileName: commandsFileContent,
}
}
func (c commandsCodeFile) GetReplaceTags() []string {
return []string{types.TagExecName}
}
var (
commandsFileName = "commands.go"
commandsFileContent = `/*Package commands implement dapp client commands*/
package commands
import "github.com/spf13/cobra"
/*
* 实现合约对应客户端
*/
// Cmd ${EXECNAME} client command
func Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "${EXECNAME}",
Short: "${EXECNAME} command",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
//add sub command
)
return cmd
}
`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
"github.com/33cn/chain33/cmd/tools/types"
)
func init() {
base.RegisterCodeFile(execCode{})
base.RegisterCodeFile(execLocalCode{})
base.RegisterCodeFile(execDelLocalCode{})
}
type execCode struct {
executorCodeFile
}
func (execCode) GetFiles() map[string]string {
return map[string]string{
execName: execContent,
}
}
func (execCode) GetReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagClassName, types.TagExecFileContent}
}
type execLocalCode struct {
executorCodeFile
}
func (execLocalCode) GetFiles() map[string]string {
return map[string]string{
execLocalName: execLocalContent,
}
}
func (execLocalCode) GetReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagExecLocalFileContent}
}
type execDelLocalCode struct {
executorCodeFile
}
func (execDelLocalCode) GetFiles() map[string]string {
return map[string]string{
execDelName: execDelContent,
}
}
func (execDelLocalCode) GetReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagExecDelLocalFileContent}
}
var (
execName = "exec.go"
execContent = `package executor
import (
ptypes "${IMPORTPATH}/${EXECNAME}/types"
"github.com/33cn/chain33/types"
)
/*
* 实现交易的链上执行接口
* 关键数据上链(statedb)并生成交易回执(log)
*/
${EXECFILECONTENT}`
execLocalName = "exec_local.go"
execLocalContent = `package executor
import (
ptypes "${IMPORTPATH}/${EXECNAME}/types"
"github.com/33cn/chain33/types"
)
/*
* 实现交易相关数据本地执行,数据不上链
* 非关键数据,本地存储(localDB), 用于辅助查询,效率高
*/
${EXECLOCALFILECONTENT}`
execDelName = "exec_del_local.go"
execDelContent = `package executor
import (
ptypes "${IMPORTPATH}/${EXECNAME}/types"
"github.com/33cn/chain33/types"
)
/*
* 实现区块回退时本地执行的数据清除
*/
${EXECDELLOCALFILECONTENT}`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
"github.com/33cn/chain33/cmd/tools/types"
)
func init() {
base.RegisterCodeFile(executorCodeFile{})
}
type executorCodeFile struct {
base.DappCodeFile
}
func (c executorCodeFile) GetDirName() string {
return "executor"
}
func (c executorCodeFile) GetFiles() map[string]string {
return map[string]string{
executorName: executorContent,
kvName: kvContent,
}
}
func (c executorCodeFile) GetReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagClassName}
}
var (
executorName = "${EXECNAME}.go"
executorContent = `package executor
import (
log "github.com/33cn/chain33/common/log/log15"
ptypes "${IMPORTPATH}/${EXECNAME}/types"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
)
/*
* 执行器相关定义
* 重载基类相关接口
*/
var (
//日志
elog = log.New("module", "execs.${EXECNAME}")
)
var driverName = ptypes.${CLASSNAME}X
func init() {
ety := types.LoadExecutorType(driverName)
ety.InitFuncList(types.ListMethod(&${EXECNAME}{}))
}
// Init register dapp
func Init(name string, sub []byte) {
drivers.Register(GetName(), new${CLASSNAME}, types.GetDappFork(driverName, "Enable"))
}
type ${EXECNAME} struct {
drivers.DriverBase
}
func new${CLASSNAME}() drivers.Driver {
t := &${EXECNAME}{}
t.SetChild(t)
t.SetExecutorType(types.LoadExecutorType(driverName))
return t
}
// GetName get driver name
func GetName() string {
return new${CLASSNAME}().GetName()
}
func (*${EXECNAME}) GetDriverName() string {
return driverName
}
// CheckTx 实现自定义检验交易接口,供框架调用
func (*${EXECNAME}) CheckTx(tx *types.Transaction, index int) error {
// implement code
return nil
}
`
kvName = "kv.go"
kvContent = `package executor
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
var (
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB = "mavl-${EXECNAME}-"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB = "LODB-${EXECNAME}-"
)
`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dappcode
import (
_ "github.com/33cn/chain33/cmd/tools/gencode/dappcode/cmd" //init cmd
_ "github.com/33cn/chain33/cmd/tools/gencode/dappcode/commands" // init command
_ "github.com/33cn/chain33/cmd/tools/gencode/dappcode/executor" // init executor
_ "github.com/33cn/chain33/cmd/tools/gencode/dappcode/proto" // init proto
_ "github.com/33cn/chain33/cmd/tools/gencode/dappcode/rpc" // init rpc
_ "github.com/33cn/chain33/cmd/tools/gencode/dappcode/types" // init types
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dappcode
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
"github.com/33cn/chain33/cmd/tools/types"
)
func init() {
base.RegisterCodeFile(pluginCodeFile{})
}
type pluginCodeFile struct {
base.DappCodeFile
}
func (c pluginCodeFile) GetFiles() map[string]string {
return map[string]string{
pluginName: pluginContent,
}
}
func (c pluginCodeFile) GetReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagClassName}
}
var (
pluginName = "plugin.go"
pluginContent = `
package ${EXECNAME}
import (
"${IMPORTPATH}/${EXECNAME}/commands"
"${IMPORTPATH}/${EXECNAME}/types"
"${IMPORTPATH}/${EXECNAME}/executor"
"${IMPORTPATH}/${EXECNAME}/rpc"
"github.com/33cn/chain33/pluginmgr"
)
/*
* 初始化dapp相关的组件
*/
func init() {
pluginmgr.Register(&pluginmgr.PluginBase{
Name: types.${CLASSNAME}X,
ExecName: executor.GetName(),
Exec: executor.Init,
Cmd: commands.Cmd,
RPC: rpc.Init,
})
}`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package proto
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
"github.com/33cn/chain33/cmd/tools/types"
)
func init() {
base.RegisterCodeFile(protoBase{})
base.RegisterCodeFile(protoFile{})
}
type protoBase struct {
base.DappCodeFile
}
func (protoBase) GetDirName() string {
return "proto"
}
func (protoBase) GetFiles() map[string]string {
return map[string]string{
protoShellName: protoShellContent,
makeName: makeContent,
}
}
type protoFile struct {
protoBase
}
func (protoFile) GetFiles() map[string]string {
return map[string]string{
protoFileName: protoFileContent,
}
}
func (protoFile) GetReplaceTags() []string {
return []string{types.TagProtoFileContent, types.TagProtoFileAppend, types.TagExecName}
}
var (
protoShellName = "create_protobuf.sh"
protoShellContent = `#!/bin/sh
# proto生成命令,将pb.go文件生成到types目录下
protoc --go_out=plugins=grpc:../types ./*.proto
`
makeName = "Makefile"
makeContent = `all:
./create_protobuf.sh
`
protoFileName = "${EXECNAME}.proto"
protoFileContent = `${PROTOFILECONTENT}
${PROTOFILEAPPEND}`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
"github.com/33cn/chain33/cmd/tools/types"
)
func init() {
base.RegisterCodeFile(rpcCodeFile{})
}
type rpcCodeFile struct {
base.DappCodeFile
}
func (c rpcCodeFile) GetDirName() string {
return "rpc"
}
func (c rpcCodeFile) GetFiles() map[string]string {
return map[string]string{
rpcName: rpcContent,
typesName: typesContent,
}
}
func (c rpcCodeFile) GetReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagClassName}
}
var (
rpcName = "rpc.go"
rpcContent = `package rpc
/*
* 实现json rpc和grpc service接口
* json rpc用Jrpc结构作为接收实例
* grpc使用channelClient结构作为接收实例
*/
`
typesName = "types.go"
typesContent = `package rpc
import (
ptypes "${IMPORTPATH}/${EXECNAME}/types"
rpctypes "github.com/33cn/chain33/rpc/types"
)
/*
* rpc相关结构定义和初始化
*/
// 实现grpc的service接口
type channelClient struct {
rpctypes.ChannelClient
}
// Jrpc 实现json rpc调用实例
type Jrpc struct {
cli *channelClient
}
// Grpc grpc
type Grpc struct {
*channelClient
}
// Init init rpc
func Init(name string, s rpctypes.RPCServer) {
cli := &channelClient{}
grpc := &Grpc{channelClient: cli}
cli.Init(name, s, &Jrpc{cli: cli}, grpc)
//存在grpc service时注册grpc server,需要生成对应的pb.go文件
ptypes.Register${CLASSNAME}Server(s.GRPC(), grpc)
}`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package types
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
"github.com/33cn/chain33/cmd/tools/types"
)
func init() {
base.RegisterCodeFile(typesCode{})
}
type typesCode struct {
base.DappCodeFile
}
func (c typesCode) GetDirName() string {
return "types"
}
func (c typesCode) GetFiles() map[string]string {
return map[string]string{
typesName: typesContent,
}
}
func (c typesCode) GetReplaceTags() []string {
return []string{types.TagExecName, types.TagClassName,
types.TagActionIDText, types.TagTyLogActionType,
types.TagLogMapText, types.TagTypeMapText}
}
var (
typesName = "${EXECNAME}.go"
typesContent = `package types
import (
"encoding/json"
"github.com/33cn/chain33/types"
)
/*
* 交易相关类型定义
* 交易action通常有对应的log结构,用于交易回执日志记录
* 每一种action和log需要用id数值和name名称加以区分
*/
// action类型id值
${ACTIONIDTEXT}
// log类型id值
${TYLOGACTIONTYPE}
var (
//${CLASSNAME}X 执行器名称定义
${CLASSNAME}X = "${EXECNAME}"
//定义action的name和id
actionMap = ${TYPEMAPTEXT}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap = ${LOGMAPTEXT}
)
func init() {
types.AllowUserExec = append(types.AllowUserExec, []byte(${CLASSNAME}X))
types.RegistorExecutor(${CLASSNAME}X, newType())
}
type ${EXECNAME}Type struct {
types.ExecTypeBase
}
func newType() *${EXECNAME}Type {
c := &${EXECNAME}Type{}
c.SetChild(c)
return c
}
// GetPayload 获取合约action结构
func (t *${EXECNAME}Type) GetPayload() types.Message {
return &${CLASSNAME}Action{}
}
// GeTypeMap 获取合约action的id和name信息
func (t *${EXECNAME}Type) GetTypeMap() map[string]int32 {
return actionMap
}
// GetLogMap 获取合约log相关信息
func (t *${EXECNAME}Type) GetLogMap() map[int64]*types.LogInfo {
return logMap
}
// CreateTx 重载基类接口,实现本合约交易创建,供框架调用
func (t *${EXECNAME}Type) CreateTx(action string, message json.RawMessage) (*types.Transaction, error) {
var tx *types.Transaction
// pseudo code
//if action == someAction
//return new tx
return tx, types.ErrNotSupport
}
`
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gencode
import (
"github.com/33cn/chain33/cmd/tools/gencode/base"
_ "github.com/33cn/chain33/cmd/tools/gencode/dappcode" //init dapp code
)
//GetCodeFilesWithType get code file with type
func GetCodeFilesWithType(typeName string) []base.ICodeFile {
if fileArr, ok := base.CodeFileManager[typeName]; ok {
return fileArr
}
return nil
}
# chain33 gendapp
根据定义的合约protobuf原型文件,自动生成chain33 dapp基本代码
### 编译
```
//本地存在chain33代码,该步骤可省略
$ git clone https://github.com/33cn/chain33.git $GOPATH/src/github.com/33cn/chain33
//编译chain33 tools
$ go build -i -o $GOPATH/bin/chain33-tool github.com/33cn/chain33/cmd/tools
```
### 使用
```
//查看命令使用方法
$ chain33-tool gendapp --help
Usage:
tools gendapp [flags]
Flags:
-h, --help help for gendapp
-n, --name string dapp name
-o, --output string go package for output (default github.com/33cn/plugin/plugin/dapp/)
-p, --proto string dapp protobuf file path
```
* -n 指定合约名字,不能含有空格和特殊字符
* -p 指定合约的protobuf文件
* -o 生成代码的输出目录路径,此处是go包路径,及相对于$GOPATH/src的路径,
默认为官方项目路径($GOPATH/src/github.com/33cn/plugin/plugin/dapp/)
举例:
```
// 默认路径生成名为demo的合约代码
$ chain33-tool gendapp -n demo -p ./demo.proto
// 指定输出包路径
$ chain33-tool gendapp -n demo -p ./demo.proto -o github.com/33cn/chain33/plugin/dapp/
//生成proto
cd proto && chmod +x ./create_protobuf.sh && make
```
### proto规范
* 定义合约交易行为结构,采用**oneof value**形式,且名称必须为**NameAction**格式,
如demo合约,定义echo和hello两种交易行为
```
message DemoAction {
oneof value {
DemoHello hello = 1;
DemoEcho echo = 2;
}
int32 ty = 3;
}
```
* 定义service,直接以合约名作为名称
```
service demo {
}
```
### 代码
#####目录结构,以demo合约为例
```
demo
├── cmd //包含官方ci集成相关脚本
│   ├── build.sh
│   └── Makefile
├── commands //合约客户端模块
│   └── commands.go
├── executor //执行器模块
│   ├── demo.go
│   ├── exec_del_local.go
│   ├── exec.go
│   ├── exec_local.go
│   └── kv.go
├── plugin.go
├── proto //proto文件及生成pb.go命令
│   ├── create_protobuf.sh
│   ├── demo.proto
│   └── Makefile
├── rpc //rpc模块
│   ├── rpc.go
│   └── types.go
└── types //类型模块
└── demo.go
```
##### 后续开发
在生成代码基础上,需要实现交易创建,执行,及所需rpc服务,初次开发可以参考官方的echo合约
> github.com/33cn/plugin/plugin/dapp/echo
......@@ -9,13 +9,12 @@ import (
"github.com/33cn/chain33/cmd/tools/commands"
"github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/common/log/log15"
"github.com/spf13/cobra"
)
var (
mlog = log15.New("module", "tools")
)
//var (
// mlog = log15.New("module", "tools")
//)
func main() {
log.SetLogLevel("debug")
......@@ -29,6 +28,7 @@ func addCommands(rootCmd *cobra.Command) {
commands.ImportCmd(),
commands.UpdateInitCmd(),
commands.CreatePluginCmd(),
commands.GenDappCmd(),
)
}
......@@ -40,7 +40,7 @@ func runCommands() {
addCommands(rootCmd)
if err := rootCmd.Execute(); err != nil {
mlog.Error("Execute command failed.", "error", err)
//mlog.Error("Execute command failed.", "error", err)
os.Exit(1)
}
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package strategy
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/33cn/chain33/cmd/tools/tasks"
"github.com/33cn/chain33/cmd/tools/types"
"github.com/33cn/chain33/cmd/tools/util"
)
type genDappStrategy struct {
strategyBasic
dappName string
dappDir string
dappProto string
packagePath string
}
func (ad *genDappStrategy) Run() error {
fmt.Println("Begin generate chain33 dapp code.")
defer fmt.Println("End generate chain33 dapp code.")
if !ad.initMember() {
return fmt.Errorf("InitError")
}
return ad.runImpl()
}
func (ad *genDappStrategy) checkParamValid() bool {
return true
}
func (ad *genDappStrategy) initMember() bool {
dappName, _ := ad.getParam(types.KeyExecutorName)
outDir, _ := ad.getParam(types.KeyDappOutDir)
protoPath, _ := ad.getParam(types.KeyProtobufFile)
//统一转为小写字母
dappName = strings.ToLower(dappName)
if strings.Contains(dappName, " ") {
mlog.Error("InitGenDapp", "Err", "invalid dapp name", "name", dappName)
return false
}
goPath := os.Getenv("GOPATH")
if goPath == "" {
mlog.Error("InitGenDapp", "Err", "$GOPATH not exist")
return false
}
// 默认输出到plugin项目的plugin/dapp/目录下
if outDir == "" {
outDir = filepath.Join("github.com", "33cn", "plugin", "plugin", "dapp")
}
//兼容win 反斜杠路径
packPath := strings.Replace(filepath.Join(outDir), string(filepath.Separator), "/", -1)
//绝对路径
dappRootDir := filepath.Join(goPath, "src", outDir, dappName)
//check dapp output directory exist
if util.CheckPathExisted(dappRootDir) {
mlog.Error("InitGenDapp", "Err", "generate dapp directory exist", "Dir", dappRootDir)
return false
}
if protoPath != "" {
bExist, _ := util.CheckFileExists(protoPath)
if !bExist {
mlog.Error("InitGenDapp", "Err", "specified proto file not exist", "ProtoFile", protoPath)
return false
}
}
err := os.MkdirAll(dappRootDir, os.ModePerm)
if err != nil {
mlog.Error("GenDappDir", "Err", err, "dir", dappRootDir)
return false
}
ad.dappName = dappName
ad.dappDir = dappRootDir
ad.dappProto = protoPath
ad.packagePath = packPath
return true
}
func (ad *genDappStrategy) runImpl() error {
var err error
tashSlice := ad.buildTask()
for _, task := range tashSlice {
err = task.Execute()
if err != nil {
mlog.Error("GenDappExecTaskFailed.", "error", err, "taskname", task.GetName())
break
}
}
return err
}
func (ad *genDappStrategy) buildTask() []tasks.Task {
taskSlice := make([]tasks.Task, 0)
taskSlice = append(taskSlice,
&tasks.GenDappCodeTask{
DappName: ad.dappName,
DappDir: ad.dappDir,
ProtoFile: ad.dappProto,
PackagePath: ad.packagePath,
},
&tasks.FormatDappSourceTask{
OutputFolder: ad.dappDir,
},
)
return taskSlice
}
......@@ -56,6 +56,12 @@ func New(name string) Strategy {
params: make(map[string]string),
},
}
case types.KeyGenDapp:
return &genDappStrategy{
strategyBasic: strategyBasic{
params: make(map[string]string),
},
}
}
return nil
}
......
......@@ -6,19 +6,12 @@ package tasks
import (
"fmt"
"regexp"
"strings"
"github.com/33cn/chain33/cmd/tools/types"
"github.com/33cn/chain33/cmd/tools/util"
sysutil "github.com/33cn/chain33/util"
)
type actionInfoItem struct {
memberName string
memberType string
}
// CreateDappSourceTask 通过生成好的pb.go和预先设计的模板,生成反射程序源码
type CreateDappSourceTask struct {
TaskBase
......@@ -81,60 +74,20 @@ func (c *CreateDappSourceTask) init() error {
return nil
}
/**
通过正则获取Action的成员变量名和类型,其具体操作步骤如下:
1. 读取需要解析的proto文件
2. 通过搜索,定位到指定Action的起始为止
3. 使用正则获取该Action中的oneof Value的内容
4. 使用正则解析oneof Value中的内容,获取变量名和类型名
5. 将获取到的变量名去除空格,并将首字母大写
*/
func (c *CreateDappSourceTask) readActionMemberNames() error {
var err error
pbContext, err := util.ReadFile(c.ProtoFile)
if err != nil {
return err
}
context := string(pbContext)
// 如果文件中含有与ActionName部分匹配的文字,则会造成搜索到多个
index := strings.Index(context, c.ActionName)
if index < 0 {
return fmt.Errorf("Action %s Not Existed", c.ActionName)
}
expr := fmt.Sprintf(`\s*oneof\s+value\s*{\s+([\w\s=;]*)\}`)
reg := regexp.MustCompile(expr)
oneOfValueStrs := reg.FindAllStringSubmatch(string(pbContext), index)
expr = fmt.Sprintf(`\s+(\w+)([\s\w]+)=\s+(\d+);`)
reg = regexp.MustCompile(expr)
members := reg.FindAllStringSubmatch(oneOfValueStrs[0][0], -1)
c.actionInfos = make([]*actionInfoItem, 0)
for _, member := range members {
memberType := strings.Replace(member[1], " ", "", -1)
memberName := strings.Replace(member[2], " ", "", -1)
// 根据proto生成pb.go的规则,成员变量首字母必须大写
memberName, _ = sysutil.MakeStringToUpper(memberName, 0, 1)
c.actionInfos = append(c.actionInfos, &actionInfoItem{
memberName: memberName,
memberType: memberType,
})
}
if len(c.actionInfos) == 0 {
return fmt.Errorf("Can Not Find %s Member Info", c.ActionName)
}
return nil
c.actionInfos, err = readDappActionFromProto(string(pbContext), c.ActionName)
return err
}
func (c *CreateDappSourceTask) createExecFile() error {
fnFmtStr := `func (c *%s) Exec_%s(payload *ptypes.%s, tx *types.Transaction, index int) (*types.Receipt, error) {
return &types.Receipt{}, nil
}
`
content := c.execHeaderTempContent
for _, info := range c.actionInfos {
content += fmt.Sprintf(fnFmtStr, c.ClsName, info.memberName, info.memberType)
}
content += formatExecContent(c.actionInfos, c.ClsName)
fileName := fmt.Sprintf("%s/executor/exec.go", c.OutputPath)
_, err := util.WriteStringToFile(fileName, content)
if err != nil {
......@@ -145,15 +98,9 @@ func (c *CreateDappSourceTask) createExecFile() error {
}
func (c *CreateDappSourceTask) createExecLocalFile() error {
fnFmtStr := `func (c *%s) ExecLocal_%s(payload *ptypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return &types.LocalDBSet{}, nil
}
`
content := c.execHeaderTempContent
for _, info := range c.actionInfos {
content += fmt.Sprintf(fnFmtStr, c.ClsName, info.memberName, info.memberType)
}
content += formatExecLocalContent(c.actionInfos, c.ClsName)
fileName := fmt.Sprintf("%s/executor/exec_local.go", c.OutputPath)
_, err := util.WriteStringToFile(fileName, content)
if err != nil {
......@@ -164,15 +111,9 @@ func (c *CreateDappSourceTask) createExecLocalFile() error {
}
func (c *CreateDappSourceTask) createExecDelLocalFile() error {
fnFmtStr := `func (c *%s) ExecDelLocal_%s(payload *ptypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return &types.LocalDBSet{}, nil
}
`
content := c.execHeaderTempContent
for _, info := range c.actionInfos {
content += fmt.Sprintf(fnFmtStr, c.ClsName, info.memberName, info.memberType)
}
content += formatExecDelLocalContent(c.actionInfos, c.ClsName)
fileName := fmt.Sprintf("%s/executor/exec_del_local.go", c.OutputPath)
_, err := util.WriteStringToFile(fileName, content)
if err != nil {
......@@ -182,42 +123,6 @@ func (c *CreateDappSourceTask) createExecDelLocalFile() error {
return nil
}
// 组成规则是 TyLog+ActionName + ActionMemberName
func (c *CreateDappSourceTask) buildActionLogTypeText() (text string, err error) {
items := fmt.Sprintf("TyLog%sUnknown = iota\n", c.ExecuteName)
for _, info := range c.actionInfos {
items += fmt.Sprintf("TyLog%s%s\n", c.ExecuteName, info.memberName)
}
text = fmt.Sprintf("const (\n%s)\n", items)
return
}
// 组成规则是 ActionName + ActionMemberName
func (c *CreateDappSourceTask) buildActionIDText() (text string, err error) {
var items string
for index, info := range c.actionInfos {
items += fmt.Sprintf("%sAction%s = %d\n", c.ExecuteName, info.memberName, index)
}
text = fmt.Sprintf("const (\n%s)\n", items)
return
}
// 返回 map[int64]*types.LogInfo
func (c *CreateDappSourceTask) buildLogMapText() (text string, err error) {
var items string
for _, info := range c.actionInfos {
items += fmt.Sprintf("\"%s\": %sAction%s,\n", info.memberName, c.ExecuteName, info.memberName)
}
text = fmt.Sprintf("map[string]int32{\n%s}", items)
return
}
// 返回 map[string]*types.LogInfo
func (c *CreateDappSourceTask) buidTypeMapText() (text string, err error) {
text = fmt.Sprintf("map[int64]*types.LogInfo{\n}")
return
}
/**
createTypeExecuteFile 根据自己的需求,创建一个types中与执行器同名的Type对照关系
需要处理的内容:
......@@ -227,22 +132,13 @@ createTypeExecuteFile 根据自己的需求,创建一个types中与执行器
4. 实现GetTypeMap()
*/
func (c *CreateDappSourceTask) createTypeExecuteFile() error {
logText, err := c.buildActionLogTypeText() // ${TYLOGACTIONTYPE}
if err != nil {
return err
}
actionIDText, err := c.buildActionIDText() // ${ACTIONIDTEXT}
if err != nil {
return err
}
logMapText, err := c.buildLogMapText() // ${LOGMAPTEXT}
if err != nil {
return err
}
typeMapText, err := c.buidTypeMapText() // ${TYPEMAPTEXT}
if err != nil {
return err
}
logText := buildActionLogTypeText(c.actionInfos, c.ExecuteName) // ${TYLOGACTIONTYPE}
actionIDText := buildActionIDText(c.actionInfos, c.ExecuteName) // ${ACTIONIDTEXT}
logMapText := buildLogMapText() // ${LOGMAPTEXT}
typeMapText := buildTypeMapText(c.actionInfos, c.ExecuteName) // ${TYPEMAPTEXT}
replacePairs := []struct {
src string
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tasks
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/33cn/chain33/cmd/tools/gencode"
"github.com/33cn/chain33/cmd/tools/types"
util2 "github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
)
// GenDappCodeTask 通过生成好的pb.go和预先设计的模板,生成反射程序源码
type GenDappCodeTask struct {
TaskBase
DappName string
DappDir string
ProtoFile string
PackagePath string
replacePairs map[string]string
}
//GetName 获取name
func (c *GenDappCodeTask) GetName() string {
return "GenDappCodeTask"
}
//Execute 执行
func (c *GenDappCodeTask) Execute() error {
mlog.Info("Execute generate dapp code task.")
c.replacePairs = make(map[string]string)
pbContext, err := util.ReadFile(c.ProtoFile)
if err != nil {
mlog.Error("ReadProtoFile", "Err", err.Error(), "proto", c.ProtoFile)
return fmt.Errorf("ReadProtoFileErr:%s", err.Error())
}
pbContent := string(pbContext)
if err = c.calcReplacePairs(pbContent); err != nil {
mlog.Error("CalcReplacePairs", "Err", err.Error())
return fmt.Errorf("CalcReplacePairsErr:%s", err.Error())
}
if err = c.genDappCode(); err != nil {
return fmt.Errorf("GenDappCodeErr:%s", err.Error())
}
return err
}
func (c *GenDappCodeTask) calcReplacePairs(pbContent string) error {
dapp := strings.ToLower(c.DappName)
className, _ := util2.MakeStringToUpper(dapp, 0, 1)
c.replacePairs[types.TagExecName] = dapp
c.replacePairs[types.TagClassName] = className
c.replacePairs[types.TagImportPath] = c.PackagePath
pbAppend := gencode.ProtoFileAppendService
if strings.Contains(pbContent, "service") {
pbAppend = ""
}
c.replacePairs[types.TagProtoFileContent] = pbContent
c.replacePairs[types.TagProtoFileAppend] = pbAppend
actionName := className + "Action"
actionInfos, err := readDappActionFromProto(pbContent, actionName)
if err != nil {
return fmt.Errorf("ReadProtoActionErr:%s", err.Error())
}
//exec
c.replacePairs[types.TagExecFileContent] = formatExecContent(actionInfos, dapp)
c.replacePairs[types.TagExecLocalFileContent] = formatExecLocalContent(actionInfos, dapp)
c.replacePairs[types.TagExecDelLocalFileContent] = formatExecDelLocalContent(actionInfos, dapp)
//types
c.replacePairs[types.TagTyLogActionType] = buildActionLogTypeText(actionInfos, className)
c.replacePairs[types.TagActionIDText] = buildActionIDText(actionInfos, className)
c.replacePairs[types.TagLogMapText] = buildLogMapText()
c.replacePairs[types.TagTypeMapText] = buildTypeMapText(actionInfos, className)
return nil
}
func (c *GenDappCodeTask) genDappCode() error {
codeTypes := gencode.GetCodeFilesWithType("dapp")
for _, code := range codeTypes {
dirPath := filepath.Join(c.DappDir, code.GetDirName())
_ = os.Mkdir(dirPath, os.ModePerm)
files := code.GetFiles()
tags := code.GetReplaceTags()
for name, content := range files {
for _, tag := range tags {
name = strings.Replace(name, tag, c.replacePairs[tag], -1)
content = strings.Replace(content, tag, c.replacePairs[tag], -1)
}
_, err := util.WriteStringToFile(filepath.Join(dirPath, name), content)
if err != nil {
mlog.Error("GenNewCodeFile", "Err", err.Error(), "CodeFile", filepath.Join(dirPath, name))
return err
}
}
}
return nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tasks
import (
"fmt"
"regexp"
"strings"
sysutil "github.com/33cn/chain33/util"
)
type actionInfoItem struct {
memberName string
memberType string
}
/**
通过正则获取Action的成员变量名和类型,其具体操作步骤如下:
1. 读取需要解析的proto文件
2. 通过搜索,定位到指定Action的起始为止
3. 使用正则获取该Action中的oneof Value的内容
4. 使用正则解析oneof Value中的内容,获取变量名和类型名
5. 将获取到的变量名去除空格,并将首字母大写
*/
func readDappActionFromProto(protoContent, actionName string) ([]*actionInfoItem, error) {
// 如果文件中含有与ActionName部分匹配的文字,则会造成搜索到多个
index := strings.Index(protoContent, actionName)
if index < 0 {
return nil, fmt.Errorf("action %s Not Existed", actionName)
}
expr := fmt.Sprintf(`\s*oneof\s+value\s*{\s+([\w\s=;]*)\}`)
reg := regexp.MustCompile(expr)
oneOfValueStrs := reg.FindAllStringSubmatch(protoContent, index)
expr = fmt.Sprintf(`\s+(\w+)([\s\w]+)=\s+(\d+);`)
reg = regexp.MustCompile(expr)
members := reg.FindAllStringSubmatch(oneOfValueStrs[0][0], -1)
actionInfos := make([]*actionInfoItem, 0)
for _, member := range members {
memberType := strings.Replace(member[1], " ", "", -1)
memberName := strings.Replace(member[2], " ", "", -1)
// 根据proto生成pb.go的规则,成员变量首字母必须大写
memberName, _ = sysutil.MakeStringToUpper(memberName, 0, 1)
actionInfos = append(actionInfos, &actionInfoItem{
memberName: memberName,
memberType: memberType,
})
}
if len(actionInfos) == 0 {
return nil, fmt.Errorf("can Not Find %s Member Info", actionName)
}
return actionInfos, nil
}
func formatExecContent(infos []*actionInfoItem, dappName string) string {
fnFmtStr := `func (c *%s) Exec_%s(payload *ptypes.%s, tx *types.Transaction, index int) (*types.Receipt, error) {
//implement code
return &types.Receipt{}, nil
}
`
content := ""
for _, info := range infos {
content += fmt.Sprintf(fnFmtStr, dappName, info.memberName, info.memberType)
}
return content
}
func formatExecLocalContent(infos []*actionInfoItem, dappName string) string {
fnFmtStr := `func (c *%s) ExecLocal_%s(payload *ptypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
//implement code
return &types.LocalDBSet{}, nil
}
`
content := ""
for _, info := range infos {
content += fmt.Sprintf(fnFmtStr, dappName, info.memberName, info.memberType)
}
return content
}
func formatExecDelLocalContent(infos []*actionInfoItem, dappName string) string {
fnFmtStr := `func (c *%s) ExecDelLocal_%s(payload *ptypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
//implement code
return &types.LocalDBSet{}, nil
}
`
content := ""
for _, info := range infos {
content += fmt.Sprintf(fnFmtStr, dappName, info.memberName, info.memberType)
}
return content
}
// 组成规则是 TyLog+ActionName + ActionMemberName
func buildActionLogTypeText(infos []*actionInfoItem, className string) (text string) {
items := fmt.Sprintf("TyLog%sUnknown = iota\n", className)
for _, info := range infos {
items += fmt.Sprintf("TyLog%s%s\n", className, info.memberName)
}
text = fmt.Sprintf("const (\n%s)\n", items)
return
}
// 组成规则是 ActionName + ActionMemberName
func buildActionIDText(infos []*actionInfoItem, className string) (text string) {
var items string
for index, info := range infos {
items += fmt.Sprintf("%sAction%s = %d\n", className, info.memberName, index)
}
text = fmt.Sprintf("const (\n%s)\n", items)
return
}
// 返回 map[string]int32
func buildTypeMapText(infos []*actionInfoItem, className string) (text string) {
var items string
for _, info := range infos {
items += fmt.Sprintf("\"%s\": %sAction%s,\n", info.memberName, className, info.memberName)
}
text = fmt.Sprintf("map[string]int32{\n%s}", items)
return
}
// 返回 map[string]*types.LogInfo
func buildLogMapText() (text string) {
text = fmt.Sprintf("map[int64]*types.LogInfo{\n\t//pseudo code\n\t//LogID: {Ty: refelct.TypeOf(LogStruct), Name: LogName},\n}")
return
}
......@@ -20,6 +20,8 @@ const (
KeyTemplateFilePath = "template_file_path"
KeyUpdateInit = "update_init"
KeyCreatePlugin = "create_plugin"
KeyGenDapp = "generate_dapp"
KeyDappOutDir = "generate_dapp_out_dir"
DefCpmConfigfile = "chain33.cpm.toml"
......@@ -36,4 +38,16 @@ const (
TagLogMapText = "${LOGMAPTEXT}"
TagTypeMapText = "${TYPEMAPTEXT}"
TagTypeName = "${TYPENAME}"
//TagImport
TagImportPath = "${IMPORTPATH}"
//Tag proto file
TagProtoFileContent = "${PROTOFILECONTENT}"
TagProtoFileAppend = "${PROTOFILEAPPEND}"
//Tag exec.go file
TagExecFileContent = "${EXECFILECONTENT}"
TagExecLocalFileContent = "${EXECLOCALFILECONTENT}"
TagExecDelLocalFileContent = "${EXECDELLOCALFILECONTENT}"
)
......@@ -38,11 +38,27 @@ const NormalVer byte = 0
const MultiSignVer byte = 5
func init() {
multisignCache, _ = lru.New(10240)
pubkeyCache, _ = lru.New(10240)
addressCache, _ = lru.New(10240)
checkAddressCache, _ = lru.New(10240)
multiCheckAddressCache, _ = lru.New(10240)
var err error
multisignCache, err = lru.New(10240)
if err != nil {
panic(err)
}
pubkeyCache, err = lru.New(10240)
if err != nil {
panic(err)
}
addressCache, err = lru.New(10240)
if err != nil {
panic(err)
}
checkAddressCache, err = lru.New(10240)
if err != nil {
panic(err)
}
multiCheckAddressCache, err = lru.New(10240)
if err != nil {
panic(err)
}
}
//ExecPubKey 计算公钥
......
......@@ -215,7 +215,11 @@ func (db *BaseDB) SetCacheSize(size int) {
if db.cache != nil {
return
}
db.cache, _ = lru.NewARC(size)
var err error
db.cache, err = lru.NewARC(size)
if err != nil {
panic(err)
}
}
//Begin call panic when Begin not rewrite
......
......@@ -149,7 +149,10 @@ func (db *GoBadgerDB) DB() *badger.DB {
//Close 关闭
func (db *GoBadgerDB) Close() {
db.db.Close()
err := db.db.Close()
if err != nil {
return
}
}
//Print 打印
......
......@@ -125,12 +125,18 @@ func (db *GoLevelDB) DB() *leveldb.DB {
//Close 关闭
func (db *GoLevelDB) Close() {
db.db.Close()
err := db.db.Close()
if err != nil {
llog.Error("Close", "error", err)
}
}
//Print 打印
func (db *GoLevelDB) Print() {
str, _ := db.db.GetProperty("leveldb.stats")
str, err := db.db.GetProperty("leveldb.stats")
if err != nil {
return
}
llog.Info("Print", "stats", str)
iter := db.db.NewIterator(nil, nil)
......
......@@ -151,14 +151,15 @@ func (b *memBatch) Delete(key []byte) {
}
func (b *memBatch) Write() error {
var err error
for _, kv := range b.writes {
if kv.v == nil {
b.db.Delete(kv.k)
err = b.db.Delete(kv.k)
} else {
b.db.Set(kv.k, kv.v)
err = b.db.Set(kv.k, kv.v)
}
}
return nil
return err
}
func (b *memBatch) ValueSize() int {
......
......@@ -60,7 +60,10 @@ func NewPegasusDB(name string, dir string, cache int) (*PegasusDB, error) {
tb, err := database.client.OpenTable(context.Background(), database.name)
if err != nil {
slog.Error("connect to pegasus error!", "pegasus", database.cfg, "error", err)
database.client.Close()
err = database.client.Close()
if err != nil {
slog.Error("database.client", "close err", err)
}
return nil, types.ErrDataBaseDamage
}
database.table = tb
......@@ -136,8 +139,14 @@ func (db *PegasusDB) DeleteSync(key []byte) error {
//Close 同步
func (db *PegasusDB) Close() {
db.table.Close()
db.client.Close()
err := db.table.Close()
if err != nil {
llog.Error("Close", "db table error", err)
}
err = db.client.Close()
if err != nil {
llog.Error("Close", "client error", err)
}
}
//Print 打印
......
......@@ -66,7 +66,8 @@ func (pool *SDBPool) get() *SDBClient {
}
func (pool *SDBPool) close() {
for _, v := range pool.clients {
v.Close()
err := v.Close()
dlog.Error("ssdb close ", "error", err)
}
}
......@@ -286,43 +287,80 @@ func (c *SDBClient) Do(args ...interface{}) ([]string, error) {
func (c *SDBClient) send(args []interface{}) error {
var packetBuf bytes.Buffer
var err error
for _, arg := range args {
switch arg := arg.(type) {
case string:
packetBuf.Write(strconv.AppendInt(nil, int64(len(arg)), 10))
packetBuf.WriteByte(ENDN)
packetBuf.WriteString(arg)
if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(arg)), 10)); err != nil {
return err
}
if err = packetBuf.WriteByte(ENDN); err != nil {
return err
}
if _, err = packetBuf.WriteString(arg); err != nil {
return err
}
case []string:
for _, a := range arg {
packetBuf.Write(strconv.AppendInt(nil, int64(len(a)), 10))
packetBuf.WriteByte(ENDN)
packetBuf.WriteString(a)
packetBuf.WriteByte(ENDN)
if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(a)), 10)); err != nil {
return err
}
if err = packetBuf.WriteByte(ENDN); err != nil {
return err
}
if _, err = packetBuf.WriteString(a); err != nil {
return err
}
if err = packetBuf.WriteByte(ENDN); err != nil {
return err
}
}
continue
case []byte:
packetBuf.Write(strconv.AppendInt(nil, int64(len(arg)), 10))
packetBuf.WriteByte(ENDN)
packetBuf.Write(arg)
if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(arg)), 10)); err != nil {
return err
}
if err = packetBuf.WriteByte(ENDN); err != nil {
return err
}
if _, err = packetBuf.Write(arg); err != nil {
return err
}
case int64:
bs := strconv.AppendInt(nil, arg, 10)
packetBuf.Write(strconv.AppendInt(nil, int64(len(bs)), 10))
packetBuf.WriteByte(ENDN)
packetBuf.Write(bs)
if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(bs)), 10)); err != nil {
return err
}
if err = packetBuf.WriteByte(ENDN); err != nil {
return err
}
if _, err = packetBuf.Write(bs); err != nil {
return err
}
case nil:
packetBuf.WriteByte(0)
packetBuf.WriteByte(ENDN)
packetBuf.WriteString("")
if err = packetBuf.WriteByte(0); err != nil {
return err
}
if err = packetBuf.WriteByte(ENDN); err != nil {
return err
}
if _, err = packetBuf.WriteString(""); err != nil {
return err
}
default:
return fmt.Errorf("bad arguments type")
}
packetBuf.WriteByte(ENDN)
if err = packetBuf.WriteByte(ENDN); err != nil {
return err
}
}
if err = packetBuf.WriteByte(ENDN); err != nil {
return err
}
packetBuf.WriteByte(ENDN)
if err := c.sock.SetWriteDeadline(time.Now().Add(time.Second * WriteTimeOut)); err != nil {
if err = c.sock.SetWriteDeadline(time.Now().Add(time.Second * WriteTimeOut)); err != nil {
return err
}
for _, err := packetBuf.WriteTo(c.sock); packetBuf.Len() > 0; {
for _, err = packetBuf.WriteTo(c.sock); packetBuf.Len() > 0; {
if err != nil {
packetBuf.Reset()
return newErrorf(err, "client socket write error")
......
......@@ -136,7 +136,10 @@ func (l *LocalDB) Commit() error {
}
it := l.txcache.Iterator(nil, nil, false)
for it.Next() {
l.cache.Set(it.Key(), it.Value())
err := l.cache.Set(it.Key(), it.Value())
if err != nil {
panic(err)
}
}
l.resetTx()
return nil
......
......@@ -125,7 +125,10 @@ func (m *MVCCHelper) Trash(version int64) error {
continue
}
if v <= version {
m.db.Delete(it.Key())
err := m.db.Delete(it.Key())
if err != nil {
mvcclog.Error("Trash Delete verson", "err", err)
}
}
}
return nil
......
......@@ -352,8 +352,14 @@ func (tx *JoinMeta) SetPayload(data types.Message) error {
if txdata, ok := data.(*JoinData); ok {
tx.data = txdata
if tx.data.Left != nil && tx.data.Right != nil {
tx.left.SetPayload(tx.data.Left)
tx.right.SetPayload(tx.data.Right)
err := tx.left.SetPayload(tx.data.Left)
if err != nil {
return err
}
err = tx.right.SetPayload(tx.data.Right)
if err != nil {
return err
}
}
return nil
}
......
......@@ -30,7 +30,10 @@ type Query struct {
func (query *Query) List(indexName string, data types.Message, primaryKey []byte, count, direction int32) (rows []*Row, err error) {
var prefix []byte
if data != nil {
query.table.getMeta().SetPayload(data)
err := query.table.getMeta().SetPayload(data)
if err != nil {
return nil, err
}
querykey := indexName
if isPrimaryIndex(indexName) {
querykey = query.table.getOpt().Primary
......
......@@ -115,9 +115,15 @@ func Sha2Sum(b []byte) []byte {
func rimpHash(in []byte, out []byte) {
sha := sha256.New()
sha.Write(in)
_, err := sha.Write(in)
if err != nil {
return
}
rim := ripemd160.New()
rim.Write(sha.Sum(nil)[:])
_, err = rim.Write(sha.Sum(nil)[:])
if err != nil {
return
}
copy(out, rim.Sum(nil))
}
......
......@@ -63,6 +63,23 @@ func (sli *Iterator) Last() *SkipValue {
return sli.node.Value
}
// Prev 获取迭代器的上一个节点
func (sli *Iterator) Prev() *Iterator {
sli.node = sli.node.Prev()
return sli
}
// Next 获取迭代器的下一个节点
func (sli *Iterator) Next() *Iterator {
sli.node = sli.node.Next()
return sli
}
// Value 获取迭代器当前的Value
func (sli *Iterator) Value() *SkipValue {
return sli.node.Value
}
// Prev 获取上一个节点
func (node *skipListNode) Prev() *skipListNode {
if node == nil || node.prev == nil {
......@@ -107,6 +124,7 @@ func NewSkipList(min *SkipValue) *SkipList {
func randomLevel() int {
level := 1
t := prob * 0xFFFF
// #nosec
for rand.Int()&0xFFFF < int(t) {
level++
if level == maxLevel {
......@@ -259,7 +277,7 @@ func (sl *SkipList) Print() {
}
}
//Walk 遍历整个结构如果cb 返回false 那么停止遍历
//Walk 遍历整个结构中SkipValue的Value,如果cb 返回false 那么停止遍历
func (sl *SkipList) Walk(cb func(value interface{}) bool) {
for e := sl.header.Next(); e != nil; e = e.Next() {
if cb == nil {
......@@ -270,3 +288,15 @@ func (sl *SkipList) Walk(cb func(value interface{}) bool) {
}
}
}
//WalkS 遍历整个结构中的SkipValue,如果cb 返回false 那么停止遍历
func (sl *SkipList) WalkS(cb func(value interface{}) bool) {
for e := sl.header.Next(); e != nil; e = e.Next() {
if cb == nil {
return
}
if !cb(e.Value) {
return
}
}
}
......@@ -78,3 +78,36 @@ func TestWalk(t *testing.T) {
l.Print()
}
func TestWalkS(t *testing.T) {
l := NewSkipList(nil)
l.Insert(s1)
l.Insert(s2)
var score [2]int64
var data [2]string
i := 0
l.WalkS(func(value interface{}) bool {
score[i] = value.(*SkipValue).Score
data[i] = value.(*SkipValue).Value.(string)
i++
return true
})
assert.Equal(t, data[0], "222")
assert.Equal(t, data[1], "111")
assert.Equal(t, int64(2), score[0])
assert.Equal(t, int64(1), score[1])
var score2 [2]int64
var data2 [2]string
i = 0
l.WalkS(func(value interface{}) bool {
score2[i] = value.(*SkipValue).Score
data2[i] = value.(*SkipValue).Value.(string)
i++
return false
})
assert.Equal(t, "222", data2[0])
assert.Equal(t, "", data2[1])
assert.Equal(t, int64(2), score2[0])
assert.Equal(t, int64(0), score2[1])
}
......@@ -13,7 +13,7 @@ import (
"github.com/33cn/chain33/types"
)
func isAllowKeyWrite(key, realExecer []byte, tx *types.Transaction, height int64) bool {
func isAllowKeyWrite(e *executor, key, realExecer []byte, tx *types.Transaction, index int) bool {
keyExecer, err := types.FindExecer(key)
if err != nil {
elog.Error("find execer ", "err", err, "key", string(key), "keyexecer", string(keyExecer))
......@@ -29,7 +29,7 @@ func isAllowKeyWrite(key, realExecer []byte, tx *types.Transaction, height int64
// 历史原因做只针对对bityuan的fork特殊化处理一下
// manage 的key 是 config
// token 的部分key 是 mavl-create-token-
if !types.IsFork(height, "ForkExecKey") {
if !types.IsFork(e.height, "ForkExecKey") {
if bytes.Equal(exec, []byte("manage")) && bytes.Equal(keyExecer, []byte("config")) {
return true
}
......@@ -53,13 +53,9 @@ func isAllowKeyWrite(key, realExecer []byte, tx *types.Transaction, height int64
//判断user.p.xxx.token 是否可以写 token 合约的内容之类的
execdriver = realExecer
}
d, err := drivers.LoadDriver(string(execdriver), height)
if err != nil {
elog.Error("load drivers error", "err", err, "execdriver", string(execdriver), "height", height)
return false
}
c := e.loadDriver(&types.Transaction{Execer: execdriver}, index)
//交给 -> friend 来判定
return d.IsFriend(execdriver, key, tx)
return c.IsFriend(execdriver, key, tx)
}
func isAllowLocalKey(execer []byte, key []byte) error {
......
......@@ -295,7 +295,10 @@ func (e *executor) execTxGroup(txs []*types.Transaction, index int) ([]*types.Re
return receipts, nil
}
}
e.commit()
err = e.commit()
if err != nil {
return nil, err
}
return receipts, nil
}
......@@ -387,7 +390,9 @@ func (e *executor) execTxOne(feelog *types.Receipt, tx *types.Transaction, index
}
if types.IsFork(e.height, "ForkStateDBSet") {
for _, v := range feelog.KV {
e.stateDB.Set(v.Key, v.Value)
if err := e.stateDB.Set(v.Key, v.Value); err != nil {
panic(err)
}
}
}
return feelog, nil
......@@ -436,16 +441,21 @@ func (e *executor) begin() {
}
}
func (e *executor) commit() {
func (e *executor) commit() error {
matchfork := types.IsFork(e.height, "ForkExecRollback")
if matchfork {
if e.stateDB != nil {
e.stateDB.Commit()
if err := e.stateDB.Commit(); err != nil {
return err
}
}
if e.localDB != nil {
e.localDB.Commit()
if err := e.localDB.Commit(); err != nil {
return err
}
}
}
return nil
}
func (e *executor) startTx() {
......@@ -500,7 +510,10 @@ func (e *executor) execTx(exec *Executor, tx *types.Transaction, index int) (*ty
if err != nil {
e.rollback()
} else {
e.commit()
err := e.commit()
if err != nil {
return nil, err
}
}
elog.Debug("exec tx = ", "index", index, "execer", string(tx.Execer), "err", err)
if api.IsAPIEnvError(err) {
......@@ -520,8 +533,7 @@ func (e *executor) execTx(exec *Executor, tx *types.Transaction, index int) (*ty
*/
func (e *executor) isAllowExec(key []byte, tx *types.Transaction, index int) bool {
realExecer := e.getRealExecName(tx, index)
height := e.height
return isAllowKeyWrite(key, realExecer, tx, height)
return isAllowKeyWrite(e, key, realExecer, tx, index)
}
func (e *executor) isExecLocalSameTime(tx *types.Transaction, index int) bool {
......@@ -573,7 +585,10 @@ func (e *executor) execLocalTx(tx *types.Transaction, r *types.ReceiptData, inde
return nil, err
}
for _, kv := range kv.KV {
e.localDB.Set(kv.Key, kv.Value)
err = e.localDB.Set(kv.Key, kv.Value)
if err != nil {
panic(err)
}
}
} else {
if len(memkvset) > 0 {
......
......@@ -332,7 +332,10 @@ func (exec *Executor) procExecAddBlock(msg *queue.Message) {
execute.enableMVCC(datas.PrevStatusHash)
var kvset types.LocalDBSet
for _, kv := range datas.KV {
execute.stateDB.Set(kv.Key, kv.Value)
err := execute.stateDB.Set(kv.Key, kv.Value)
if err != nil {
panic(err)
}
}
for name, plugin := range globalPlugins {
kvs, ok, err := plugin.CheckEnable(execute, exec.pluginEnable[name])
......@@ -353,7 +356,10 @@ func (exec *Executor) procExecAddBlock(msg *queue.Message) {
if len(kvs) > 0 {
kvset.KV = append(kvset.KV, kvs...)
for _, kv := range kvs {
execute.localDB.Set(kv.Key, kv.Value)
err := execute.localDB.Set(kv.Key, kv.Value)
if err != nil {
panic(err)
}
}
}
}
......@@ -401,7 +407,10 @@ func (exec *Executor) procExecDelBlock(msg *queue.Message) {
execute.enableMVCC(nil)
var kvset types.LocalDBSet
for _, kv := range datas.KV {
execute.stateDB.Set(kv.Key, kv.Value)
err := execute.stateDB.Set(kv.Key, kv.Value)
if err != nil {
panic(err)
}
}
for name, plugin := range globalPlugins {
kvs, ok, err := plugin.CheckEnable(execute, exec.pluginEnable[name])
......
......@@ -30,7 +30,6 @@ func TestIsModule(t *testing.T) {
}
func TestExecutorGetTxGroup(t *testing.T) {
exec := &Executor{}
execInit(nil)
var txs []*types.Transaction
addr2, priv2 := util.Genaddress()
......@@ -59,7 +58,7 @@ func TestExecutorGetTxGroup(t *testing.T) {
mainHash: nil,
parentHash: nil,
}
execute := newExecutor(ctx, exec, nil, txs, nil)
execute := newExecutor(ctx, &Executor{}, nil, txs, nil)
e := execute.loadDriver(txs[0], 0)
execute.setEnv(e)
txs2 := e.GetTxs()
......@@ -74,7 +73,7 @@ func TestExecutorGetTxGroup(t *testing.T) {
//err tx group list
txs[0].Header = nil
execute = newExecutor(ctx, exec, nil, txs, nil)
execute = newExecutor(ctx, &Executor{}, nil, txs, nil)
e = execute.loadDriver(txs[0], 0)
execute.setEnv(e)
_, err = e.GetTxGroup(len(txs) - 1)
......@@ -109,7 +108,16 @@ func TestKeyAllow(t *testing.T) {
var tx12 types.Transaction
types.Decode(tx11, &tx12)
tx12.Execer = exec
if !isAllowKeyWrite(key, exec, &tx12, int64(1)) {
ctx := &executorCtx{
stateHash: nil,
height: 1,
blocktime: time.Now().Unix(),
difficulty: 1,
mainHash: nil,
parentHash: nil,
}
execute := newExecutor(ctx, &Executor{}, nil, nil, nil)
if !isAllowKeyWrite(execute, key, exec, &tx12, 0) {
t.Error("retrieve can modify exec")
}
}
......@@ -123,7 +131,16 @@ func TestKeyAllow_evm(t *testing.T) {
var tx12 types.Transaction
types.Decode(tx11, &tx12)
tx12.Execer = exec
if !isAllowKeyWrite(key, exec, &tx12, int64(1)) {
ctx := &executorCtx{
stateHash: nil,
height: 1,
blocktime: time.Now().Unix(),
difficulty: 1,
mainHash: nil,
parentHash: nil,
}
execute := newExecutor(ctx, &Executor{}, nil, nil, nil)
if !isAllowKeyWrite(execute, key, exec, &tx12, 0) {
t.Error("user.evm.hash can modify exec")
}
//assert.Nil(t, t)
......
......@@ -129,7 +129,10 @@ func updateAddrTxsCount(cachedb dbm.KVDB, addr string, amount int64, isadd bool)
} else {
txscount -= amount
}
setAddrTxsCount(cachedb, addr, txscount)
err = setAddrTxsCount(cachedb, addr, txscount)
if err != nil {
return nil, err
}
//keyvalue
return getAddrTxsCountKV(addr, txscount), nil
}
......@@ -83,7 +83,11 @@ func getTxIndex(executor *executor, tx *types.Transaction, receipt *types.Receip
ety := types.LoadExecutorType(string(tx.Execer))
// none exec has not execType
if ety != nil {
txinf.Assets, _ = ety.GetAssets(tx)
var err error
txinf.Assets, err = ety.GetAssets(tx)
if err != nil {
elog.Error("getTxIndex ", "GetAssets err", err)
}
}
txIndexInfo.index = &txinf
......
......@@ -87,7 +87,10 @@ func NewAddrBook(cfg *types.P2P) *AddrBook {
cfg: cfg,
Quit: make(chan struct{}, 1),
}
a.Start()
err := a.Start()
if err != nil {
return nil
}
return a
}
......@@ -210,7 +213,10 @@ func (a *AddrBook) saveToDb() {
return
}
log.Debug("saveToDb", "addrs", string(jsonBytes))
a.bookDb.Set([]byte(addrkeyTag), jsonBytes)
err = a.bookDb.Set([]byte(addrkeyTag), jsonBytes)
if err != nil {
panic(err)
}
}
func (a *AddrBook) genPubkey(privkey string) string {
......@@ -236,11 +242,14 @@ func (a *AddrBook) genPubkey(privkey string) string {
func (a *AddrBook) loadDb() bool {
a.bookDb = db.NewDB("addrbook", a.cfg.Driver, a.cfg.DbPath, a.cfg.DbCache)
privkey, _ := a.bookDb.Get([]byte(privKeyTag))
if len(privkey) == 0 {
privkey, err := a.bookDb.Get([]byte(privKeyTag))
if len(privkey) == 0 || err != nil {
a.initKey()
privkey, _ := a.GetPrivPubKey()
a.bookDb.Set([]byte(privKeyTag), []byte(privkey))
err := a.bookDb.Set([]byte(privKeyTag), []byte(privkey))
if err != nil {
panic(err)
}
return false
}
......
......@@ -39,7 +39,10 @@ func (Comm) AddrRouteble(addrs []string) []string {
//log.Error("AddrRouteble", "DialTimeout", err.Error())
continue
}
conn.Close()
err = conn.Close()
if err != nil {
log.Error("AddrRouteble", "conn.Close err", err.Error())
}
enableAddrs = append(enableAddrs, addr)
}
return enableAddrs
......@@ -81,7 +84,7 @@ func (c Comm) dialPeerWithAddress(addr *NetAddress, persistent bool, node *Node)
peer, err := c.newPeerFromConn(conn, addr, node)
if err != nil {
conn.Close()
err = conn.Close()
return nil, err
}
peer.SetAddr(addr)
......@@ -261,7 +264,11 @@ func (c Comm) reportPeerStat(peer *Peer) {
func (c Comm) BytesToInt32(b []byte) int32 {
bytesBuffer := bytes.NewBuffer(b)
var tmp int32
binary.Read(bytesBuffer, binary.LittleEndian, &tmp)
err := binary.Read(bytesBuffer, binary.LittleEndian, &tmp)
if err != nil {
log.Error("BytesToInt32", "binary.Read err", err.Error())
return tmp
}
return tmp
}
......@@ -269,7 +276,10 @@ func (c Comm) BytesToInt32(b []byte) int32 {
func (c Comm) Int32ToBytes(n int32) []byte {
tmp := n
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.LittleEndian, tmp)
err := binary.Write(bytesBuffer, binary.LittleEndian, tmp)
if err != nil {
return nil
}
return bytesBuffer.Bytes()
}
......
......@@ -61,6 +61,9 @@ func NewMConnectionWithConfig(cfg *MConnConfig) *MConnection {
// Close mconnection
func (c *MConnection) Close() {
c.gconn.Close()
err := c.gconn.Close()
if err != nil {
log.Error("Mconnection", "Close err", err)
}
log.Debug("Mconnection", "Close", "^_^!")
}
......@@ -19,7 +19,11 @@ var Filter = NewFilter()
// NewFilter produce a filter object
func NewFilter() *Filterdata {
filter := new(Filterdata)
filter.regRData, _ = lru.New(P2pCacheTxSize)
var err error
filter.regRData, err = lru.New(P2pCacheTxSize)
if err != nil {
panic(err)
}
return filter
}
......
......@@ -29,7 +29,10 @@ func (l *listener) Start() {
// Close listener close
func (l *listener) Close() {
l.netlistener.Close()
err := l.netlistener.Close()
if err != nil {
log.Error("Close", "netlistener.Close() err", err)
}
go l.server.Stop()
l.p2pserver.Close()
log.Info("stop", "listener", "close")
......
......@@ -112,7 +112,10 @@ func Map(m Interface, c chan struct{}, protocol string, extport, intport int, na
refresh.Stop()
log.Println("Deleting port mapping")
m.DeleteMapping(protocol, extport, intport)
err := m.DeleteMapping(protocol, extport, intport)
if err != nil {
return
}
}()
if err := m.AddMapping(protocol, extport, intport, name, mapTimeout); err != nil {
log.Println("Couldn't add port mapping", "err", err)
......
......@@ -68,7 +68,10 @@ func (n *upnp) AddMapping(protocol string, extport, intport int, desc string, li
fmt.Println("internalAddress:", ip)
protocol = strings.ToUpper(protocol)
lifetimeS := uint32(lifetime / time.Second)
n.DeleteMapping(protocol, extport, intport)
err = n.DeleteMapping(protocol, extport, intport)
if err != nil {
return err
}
return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS)
}
......
......@@ -164,7 +164,10 @@ func (na *NetAddress) DialTimeout(version int32) (*grpc.ClientConn, error) {
if err != nil && !isCompressSupport(err) {
//compress not support
log.Error("compress not supprot , rollback to uncompress version", "addr", na.String())
conn.Close()
err = conn.Close()
if err != nil {
log.Error("conn", "close err", err)
}
ch2 := make(chan grpc.ServiceConfig, 1)
ch2 <- P2pComm.GrpcConfig()
log.Debug("NetAddress", "Dial with unCompressor", na.String())
......@@ -174,7 +177,10 @@ func (na *NetAddress) DialTimeout(version int32) (*grpc.ClientConn, error) {
if err != nil {
log.Debug("grpc DialCon Uncompressor", "did not connect", err)
if conn != nil {
conn.Close()
errs := conn.Close()
if errs != nil {
log.Error("conn", "close err", errs)
}
}
return nil, err
}
......
......@@ -368,12 +368,15 @@ func (n *Node) detectNodeAddr() {
if cfg.IsSeed {
externalPort = defaultPort
} else {
exportBytes, _ := n.nodeInfo.addrBook.bookDb.Get([]byte(externalPortTag))
exportBytes, err := n.nodeInfo.addrBook.bookDb.Get([]byte(externalPortTag))
if len(exportBytes) != 0 {
externalPort = int(P2pComm.BytesToInt32(exportBytes))
} else {
externalPort = defalutNatPort
}
if err != nil {
log.Error("bookDb Get", "externalPortTag fail err:", err)
}
}
externaladdr = fmt.Sprintf("%v:%v", externalIP, externalPort)
......@@ -444,8 +447,11 @@ func (n *Node) natMapPort() {
return
}
n.nodeInfo.addrBook.bookDb.Set([]byte(externalPortTag),
err = n.nodeInfo.addrBook.bookDb.Set([]byte(externalPortTag),
P2pComm.Int32ToBytes(int32(n.nodeInfo.GetExternalAddr().Port))) //把映射成功的端口信息刷入db
if err != nil {
panic(err)
}
log.Info("natMapPort", "export insert into db", n.nodeInfo.GetExternalAddr().Port)
n.nodeInfo.natResultChain <- true
refresh := time.NewTimer(mapUpdateInterval)
......@@ -470,7 +476,10 @@ func (n *Node) deleteNatMapPort() {
if n.nodeInfo.OutSide() {
return
}
nat.Any().DeleteMapping("TCP", int(n.nodeInfo.GetExternalAddr().Port), defaultPort)
err := nat.Any().DeleteMapping("TCP", int(n.nodeInfo.GetExternalAddr().Port), defaultPort)
if err != nil {
log.Error("deleteNatMapPort", "DeleteMapping err", err.Error())
}
}
......
......@@ -103,7 +103,10 @@ func (network *P2p) SetQueueClient(client queue.Client) {
log.Info("p2p", "setqueuecliet", "ok")
network.node.Start()
network.subP2pMsg()
network.loadP2PPrivKeyToWallet()
err := network.loadP2PPrivKeyToWallet()
if err != nil {
return
}
}()
}
......
......@@ -131,14 +131,20 @@ func (m *Cli) GetMemPool(msg *queue.Message, taskindex int64) {
invdatas, recerr := datacli.Recv()
if recerr != nil && recerr != io.EOF {
log.Error("GetMemPool", "err", recerr.Error())
datacli.CloseSend()
err = datacli.CloseSend()
if err != nil {
log.Error("datacli", "close err", err)
}
continue
}
for _, invdata := range invdatas.Items {
Txs = append(Txs, invdata.GetTx())
}
datacli.CloseSend()
err = datacli.CloseSend()
if err != nil {
log.Error("datacli", "CloseSend err", err)
}
break
}
msg.Reply(m.network.client.NewMessage("mempool", pb.EventReplyTxList, &pb.ReplyTxList{Txs: Txs}))
......@@ -380,7 +386,10 @@ func (m *Cli) GetHeaders(msg *queue.Message, taskindex int64) {
client := m.network.node.nodeInfo.client
msg := client.NewMessage("blockchain", pb.EventAddBlockHeaders, &pb.HeadersPid{Pid: pid[0], Headers: &pb.Headers{Items: headers.GetHeaders()}})
client.Send(msg, false)
err = client.Send(msg, false)
if err != nil {
log.Error("send", "to blockchain EventAddBlockHeaders msg Err", err.Error())
}
}
}
}
......@@ -531,7 +540,10 @@ func (m *Cli) GetBlocks(msg *queue.Message, taskindex int64) {
return
case blockpid := <-bChan:
newmsg := m.network.node.nodeInfo.client.NewMessage("blockchain", pb.EventSyncBlock, blockpid)
m.network.node.nodeInfo.client.SendTimeout(newmsg, false, 60*time.Second)
err := m.network.node.nodeInfo.client.SendTimeout(newmsg, false, 60*time.Second)
if err != nil {
log.Error("send", "to blockchain EventSyncBlock msg err", err)
}
i++
if i == len(MaxInvs.GetInvs()) {
return
......
......@@ -179,7 +179,10 @@ func (s *P2pserver) BroadCastTx(ctx context.Context, in *pb.P2PTx) (*pb.Reply, e
log.Debug("p2pServer RECV TRANSACTION", "in", in)
client := s.node.nodeInfo.client
msg := client.NewMessage("mempool", pb.EventTx, in.Tx)
client.Send(msg, false)
err := client.Send(msg, false)
if err != nil {
return nil, err
}
return &pb.Reply{IsOk: true, Msg: []byte("ok")}, nil
}
......@@ -479,7 +482,10 @@ func (s *P2pserver) ServerStreamRead(stream pb.P2Pgservice_ServerStreamReadServe
"block size(KB)", float32(len(pb.Encode(block)))/1024, "block hash", blockhash)
if block.GetBlock() != nil {
msg := s.node.nodeInfo.client.NewMessage("blockchain", pb.EventBroadcastAddBlock, &pb.BlockPid{Pid: peername, Block: block.GetBlock()})
s.node.nodeInfo.client.Send(msg, false)
err := s.node.nodeInfo.client.Send(msg, false)
if err != nil {
log.Error("send", "to blockchain EventBroadcastAddBlock msg err", err)
}
}
} else if tx := in.GetTx(); tx != nil {
......@@ -495,7 +501,10 @@ func (s *P2pserver) ServerStreamRead(stream pb.P2Pgservice_ServerStreamReadServe
Filter.ReleaseLock()
if tx.GetTx() != nil {
msg := s.node.nodeInfo.client.NewMessage("mempool", pb.EventTx, tx.GetTx())
s.node.nodeInfo.client.Send(msg, false)
err := s.node.nodeInfo.client.Send(msg, false)
if err != nil {
log.Error("send", "to mempool EventTx msg err", err)
}
}
//Filter.RegRecvData(txhash)
......
......@@ -195,7 +195,10 @@ func (p *Peer) sendStream() {
//send ping package
ping, err := P2pComm.NewPingData(p.node.nodeInfo)
if err != nil {
resp.CloseSend()
errs := resp.CloseSend()
if errs != nil {
log.Error("CloseSend", "err", errs)
}
cancel()
time.Sleep(time.Second)
continue
......@@ -203,7 +206,10 @@ func (p *Peer) sendStream() {
p2pdata := new(pb.BroadCastData)
p2pdata.Value = &pb.BroadCastData_Ping{Ping: ping}
if err := resp.Send(p2pdata); err != nil {
resp.CloseSend()
errs := resp.CloseSend()
if errs != nil {
log.Error("CloseSend", "err", errs)
}
cancel()
log.Error("sendStream", "sendping", err)
time.Sleep(time.Second)
......@@ -216,7 +222,10 @@ func (p *Peer) sendStream() {
Softversion: v.GetVersion(), Peername: peername}}
if err := resp.Send(p2pdata); err != nil {
resp.CloseSend()
errs := resp.CloseSend()
if errs != nil {
log.Error("CloseSend", "err", errs)
}
cancel()
log.Error("sendStream", "sendping", err)
time.Sleep(time.Second)
......@@ -231,7 +240,10 @@ func (p *Peer) sendStream() {
select {
case task := <-p.taskChan:
if !p.GetRunning() {
resp.CloseSend()
errs := resp.CloseSend()
if errs != nil {
log.Error("CloseSend", "err", errs)
}
cancel()
log.Error("sendStream peer is not running")
return
......@@ -270,7 +282,10 @@ func (p *Peer) sendStream() {
p.node.nodeInfo.blacklist.Add(p.Addr(), 3600)
}
time.Sleep(time.Second) //have a rest
resp.CloseSend()
errs := resp.CloseSend()
if errs != nil {
log.Error("CloseSend", "err", errs)
}
cancel()
break SEND_LOOP //下一次外循环重新获取stream
......@@ -280,7 +295,10 @@ func (p *Peer) sendStream() {
case <-timeout.C:
if !p.GetRunning() {
log.Error("sendStream timeout")
resp.CloseSend()
errs := resp.CloseSend()
if errs != nil {
log.Error("CloseSend", "err", errs)
}
cancel()
return
}
......@@ -318,14 +336,20 @@ func (p *Peer) readStream() {
var hash [64]byte
for {
if !p.GetRunning() {
resp.CloseSend()
errs := resp.CloseSend()
if errs != nil {
log.Error("CloseSend", "err", errs)
}
return
}
data, err := resp.Recv()
P2pComm.CollectPeerStat(err, p)
if err != nil {
log.Error("readStream", "recv,err:", err.Error())
resp.CloseSend()
errs := resp.CloseSend()
if errs != nil {
log.Error("CloseSend", "err", errs)
}
if grpc.Code(err) == codes.Unimplemented { //maybe order peers delete peer to BlackList
p.node.nodeInfo.blacklist.Add(p.Addr(), 3600)
}
......@@ -386,7 +410,10 @@ func (p *Peer) readStream() {
Filter.RegRecvData(txhash)
Filter.ReleaseLock()
msg := p.node.nodeInfo.client.NewMessage("mempool", pb.EventTx, tx.GetTx())
p.node.nodeInfo.client.Send(msg, false)
errs := p.node.nodeInfo.client.Send(msg, false)
if errs != nil {
log.Error("send", "to mempool EventTx msg Error", err.Error())
}
//Filter.RegRecvData(txhash) //登记
}
}
......
......@@ -153,6 +153,7 @@ func (client *client) getTopic() string {
}
func (client *client) setTopic(topic string) {
// #nosec
atomic.StorePointer(&client.topic, unsafe.Pointer(&topic))
}
......
......@@ -29,7 +29,11 @@ type channelClient struct {
// Init channel client
func (c *channelClient) Init(q queue.Client, api client.QueueProtocolAPI) {
if api == nil {
api, _ = client.New(q, nil)
var err error
api, err = client.New(q, nil)
if err != nil {
panic(err)
}
}
c.QueueProtocolAPI = api
c.accountdb = account.NewCoinsAccount()
......
......@@ -2,9 +2,11 @@ package grpcclient
import (
"sync"
"time"
"github.com/33cn/chain33/types"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
)
// paraChainGrpcRecSize 平行链receive最大100M
......@@ -28,9 +30,14 @@ func NewMainChainClient(grpcaddr string) (types.Chain33Client, error) {
if paraRemoteGrpcClient == "" {
paraRemoteGrpcClient = "127.0.0.1:8802"
}
kp := keepalive.ClientParameters{
Time: time.Second * 5,
Timeout: time.Second * 20,
PermitWithoutStream: true,
}
conn, err := grpc.Dial(NewMultipleURL(paraRemoteGrpcClient), grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(paraChainGrpcRecSize)))
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(paraChainGrpcRecSize)),
grpc.WithKeepaliveParams(kp))
if err != nil {
return nil, err
}
......
......@@ -8,6 +8,8 @@ import (
"encoding/hex"
"time"
"strings"
pb "github.com/33cn/chain33/types"
"golang.org/x/net/context"
)
......@@ -338,7 +340,10 @@ func (g *Grpc) GetFatalFailure(ctx context.Context, in *pb.ReqNil) (*pb.Int32, e
func (g *Grpc) CloseQueue(ctx context.Context, in *pb.ReqNil) (*pb.Reply, error) {
go func() {
time.Sleep(time.Millisecond * 100)
g.cli.CloseQueue()
_, err := g.cli.CloseQueue()
if err != nil {
log.Error("CloseQueue", "Error", err)
}
}()
return &pb.Reply{IsOk: true}, nil
......@@ -380,5 +385,9 @@ func (g *Grpc) QueryRandNum(ctx context.Context, in *pb.ReqRandHash) (*pb.ReplyH
// GetFork get fork height by fork key
func (g *Grpc) GetFork(ctx context.Context, in *pb.ReqKey) (*pb.Int64, error) {
keys := strings.Split(string(in.Key), "-")
if len(keys) == 2 {
return &pb.Int64{Data: pb.GetDappFork(keys[0], keys[1])}, nil
}
return &pb.Int64{Data: pb.GetFork(string(in.Key))}, nil
}
......@@ -1177,3 +1177,14 @@ func TestGrpc_QueryRandNum(t *testing.T) {
_, err := g.QueryRandNum(getOkCtx(), &pb.ReqRandHash{})
assert.NoError(t, err)
}
func TestGrpc_GetFork(t *testing.T) {
pb.SetDappFork("local", "para", "fork100", 100)
val, err := g.GetFork(getOkCtx(), &pb.ReqKey{Key: []byte("para-fork100")})
assert.NoError(t, err)
assert.Equal(t, int64(100), val.Data)
val, err = g.GetFork(getOkCtx(), &pb.ReqKey{Key: []byte("ForkBlockHash")})
assert.NoError(t, err)
assert.Equal(t, int64(1), val.Data)
}
......@@ -135,7 +135,11 @@ func writeError(w http.ResponseWriter, r *http.Request, id uint64, errstr string
log.Debug("json marshal error, nerver happen")
return
}
w.Write(resp)
_, err = w.Write(resp)
if err != nil {
log.Debug("Write", "err", err)
return
}
}
// Listen grpcserver listen
......
......@@ -120,7 +120,10 @@ func (c *Chain33) SendTransaction(in rpctypes.RawParm, result *interface{}) erro
if err != nil {
return err
}
types.Decode(data, &parm)
err = types.Decode(data, &parm)
if err != nil {
return err
}
log.Debug("SendTransaction", "parm", parm)
var reply *types.Reply
......@@ -277,7 +280,10 @@ func (c *Chain33) GetTxByHashes(in rpctypes.ReqHashes, result *interface{}) erro
var txdetails rpctypes.TransactionDetails
if 0 != len(txs) {
for _, tx := range txs {
txDetail, _ := fmtTxDetail(tx, in.DisableDetail)
txDetail, err := fmtTxDetail(tx, in.DisableDetail)
if err != nil {
return err
}
txdetails.Txs = append(txdetails.Txs, txDetail)
}
}
......@@ -407,7 +413,10 @@ func (c *Chain33) WalletTxList(in rpctypes.ReqWalletTransactionList, result *int
}
{
var txdetails rpctypes.WalletTxDetails
rpctypes.ConvertWalletTxDetailToJSON(reply, &txdetails)
err := rpctypes.ConvertWalletTxDetailToJSON(reply, &txdetails)
if err != nil {
return err
}
*result = &txdetails
}
return nil
......@@ -863,7 +872,10 @@ func (c *Chain33) GetTotalCoins(in *types.ReqGetTotalCoins, result *interface{})
// IsSync is sync or not
func (c *Chain33) IsSync(in *types.ReqNil, result *interface{}) error {
reply, _ := c.cli.IsSync()
reply, err := c.cli.IsSync()
if err != nil {
return err
}
ret := false
if reply != nil {
ret = reply.IsOk
......@@ -874,7 +886,10 @@ func (c *Chain33) IsSync(in *types.ReqNil, result *interface{}) error {
// IsNtpClockSync is ntp clock sync
func (c *Chain33) IsNtpClockSync(in *types.ReqNil, result *interface{}) error {
reply, _ := c.cli.IsNtpClockSync()
reply, err := c.cli.IsNtpClockSync()
if err != nil {
return err
}
ret := false
if reply != nil {
ret = reply.IsOk
......@@ -983,7 +998,10 @@ func (c *Chain33) WalletCreateTx(in types.ReqCreateTransaction, result *interfac
func (c *Chain33) CloseQueue(in *types.ReqNil, result *interface{}) error {
go func() {
time.Sleep(time.Millisecond * 100)
c.cli.CloseQueue()
_, err := c.cli.CloseQueue()
if err != nil {
return
}
}()
*result = &types.Reply{IsOk: true}
......
......@@ -65,7 +65,10 @@ type JSONRPCServer struct {
// Close json rpcserver close
func (s *JSONRPCServer) Close() {
if s.l != nil {
s.l.Close()
err := s.l.Close()
if err != nil {
log.Error("JSONRPCServer close", "err", err)
}
}
if s.jrpc != nil {
s.jrpc.cli.Close()
......@@ -132,7 +135,10 @@ func (j *Grpcserver) Close() {
return
}
if j.l != nil {
j.l.Close()
err := j.l.Close()
if err != nil {
log.Error("Grpcserver close", "err", err)
}
}
if j.grpc != nil {
j.grpc.cli.Close()
......@@ -179,7 +185,10 @@ func NewJSONRPCServer(c queue.Client, api client.QueueProtocolAPI) *JSONRPCServe
j.jrpc.mainGrpcCli = grpcCli
server := rpc.NewServer()
j.s = server
server.RegisterName("Chain33", j.jrpc)
err = server.RegisterName("Chain33", j.jrpc)
if err != nil {
return nil
}
return j
}
......
......@@ -173,7 +173,7 @@ type ReplyTxList struct {
Txs []*Transaction `json:"txs"`
}
// ReplyTxList reply tx list
// ReplyProperFee reply proper fee
type ReplyProperFee struct {
ProperFee int64 `json:"properFee"`
}
......
......@@ -87,7 +87,11 @@ func (bc *BaseClient) InitClient(c queue.Client, minerstartCB func()) {
log.Info("Enter SetQueueClient method of consensus")
bc.client = c
bc.minerstartCB = minerstartCB
bc.api, _ = client.New(c, nil)
var err error
bc.api, err = client.New(c, nil)
if err != nil {
panic(err)
}
bc.InitMiner()
}
......@@ -138,7 +142,10 @@ func (bc *BaseClient) InitBlock() {
if newblock.Height == 0 {
newblock.Difficulty = types.GetP(0).PowLimitBits
}
bc.WriteBlock(zeroHash[:], newblock)
err := bc.WriteBlock(zeroHash[:], newblock)
if err != nil {
panic(err)
}
} else {
bc.SetCurrentBlock(block)
}
......@@ -377,7 +384,10 @@ func (bc *BaseClient) WriteBlock(prev []byte, block *types.Block) error {
//从mempool 中删除错误的交易
deltx := diffTx(rawtxs, blockdetail.Block.Txs)
if len(deltx) > 0 {
bc.delMempoolTx(deltx)
err := bc.delMempoolTx(deltx)
if err != nil {
return err
}
}
if blockdetail != nil {
bc.SetCurrentBlock(blockdetail.Block)
......
......@@ -47,8 +47,14 @@ func (pack *TransferPack) checkBalance(txInfo map[string]interface{}) bool {
logFee := logArr[0].(map[string]interface{})["log"].(map[string]interface{})
logSend := logArr[1].(map[string]interface{})["log"].(map[string]interface{})
logRecv := logArr[2].(map[string]interface{})["log"].(map[string]interface{})
fee, _ := strconv.ParseFloat(feeStr, 64)
Amount, _ := strconv.ParseFloat(interCase.Amount, 64)
fee, err := strconv.ParseFloat(feeStr, 64)
if err != nil {
return false
}
Amount, err := strconv.ParseFloat(interCase.Amount, 64)
if err != nil {
return false
}
pack.FLog.Info("TransferBalanceDetails", "TestID", pack.PackID,
"Fee", feeStr, "Amount", interCase.Amount,
......
......@@ -50,8 +50,14 @@ func (pack *WithdrawPack) checkBalance(txInfo map[string]interface{}) bool {
logWithdraw := logArr[1].(map[string]interface{})["log"].(map[string]interface{})
logSend := logArr[2].(map[string]interface{})["log"].(map[string]interface{})
logRecv := logArr[3].(map[string]interface{})["log"].(map[string]interface{})
fee, _ := strconv.ParseFloat(feeStr, 64)
Amount, _ := strconv.ParseFloat(interCase.Amount, 64)
fee, err := strconv.ParseFloat(feeStr, 64)
if err != nil {
return false
}
Amount, err := strconv.ParseFloat(interCase.Amount, 64)
if err != nil {
return false
}
pack.FLog.Info("WithdrawBalanceDetails", "TestID", pack.PackID,
"Fee", feeStr, "Amount", Amount, "Addr", interCase.Addr, "ExecAddr", withdrawFrom,
......
......@@ -65,7 +65,10 @@ func updateAddrReciver(cachedb dbm.KVDB, addr string, amount int64, isadd bool)
} else {
recv -= amount
}
setAddrReciver(cachedb, addr, recv)
err = setAddrReciver(cachedb, addr, recv)
if err != nil {
return nil, err
}
//keyvalue
return geAddrReciverKV(addr, recv), nil
}
......@@ -106,7 +106,10 @@ func (m *Action) modifyConfig(modify *types.ModifyConfig) (*types.Receipt, error
var kv []*types.KeyValue
key := types.ManaeKeyWithHeigh(modify.Key, m.height)
valueSave := types.Encode(&item)
m.db.Set([]byte(key), valueSave)
err = m.db.Set([]byte(key), valueSave)
if err != nil {
return nil, err
}
kv = append(kv, &types.KeyValue{Key: []byte(key), Value: valueSave})
log := types.ReceiptConfig{Prev: &copyItem, Current: &item}
logs = append(logs, &types.ReceiptLog{Ty: pty.TyLogModifyConfig, Log: types.Encode(&log)})
......
......@@ -64,6 +64,7 @@ func LoadDriver(name string, height int64) (driver Driver, err error) {
func LoadDriverAllow(tx *types.Transaction, index int, height int64) (driver Driver) {
exec, err := LoadDriver(string(tx.Execer), height)
if err == nil {
exec.SetEnv(height, 0, 0)
err = exec.Allow(tx, index)
}
if err != nil {
......
......@@ -76,7 +76,10 @@ func (c *KVCreator) addnoprefix(key, value []byte, set bool) *KVCreator {
}
c.kvs = append(c.kvs, &types.KeyValue{Key: key, Value: value})
if set {
c.kvdb.Set(key, value)
err := c.kvdb.Set(key, value)
if err != nil {
panic(err)
}
}
return c
}
......
......@@ -307,7 +307,10 @@ func (mem *Mempool) delBlock(block *types.Block) {
if !mem.checkExpireValid(tx) {
continue
}
mem.PushTx(tx)
err = mem.PushTx(tx)
if err != nil {
mlog.Error("mem", "push tx err", err)
}
}
}
......@@ -334,7 +337,11 @@ func (mem *Mempool) sendTxToP2P(tx *types.Transaction) {
panic("client not bind message queue.")
}
msg := mem.client.NewMessage("p2p", types.EventTxBroadcast, tx)
mem.client.Send(msg, false)
err := mem.client.Send(msg, false)
if err != nil {
mlog.Error("tx sent to p2p", "tx.Hash", common.ToHex(tx.Hash()))
return
}
mlog.Debug("tx sent to p2p", "tx.Hash", common.ToHex(tx.Hash()))
}
......
......@@ -53,7 +53,10 @@ func (cache *txCache) Remove(hash string) {
return
}
tx := item.Value
cache.qcache.Remove(hash)
err = cache.qcache.Remove(hash)
if err != nil {
mlog.Error("Remove", "cache Remove err", err)
}
cache.AccountTxIndex.Remove(tx)
cache.LastTxCache.Remove(tx)
}
......@@ -99,7 +102,10 @@ func (cache *txCache) Push(tx *types.Transaction) error {
if err != nil {
return err
}
cache.AccountTxIndex.Push(tx)
err = cache.AccountTxIndex.Push(tx)
if err != nil {
return err
}
cache.LastTxCache.Push(tx)
return nil
}
......
......@@ -9,6 +9,7 @@ import (
"github.com/33cn/chain33/types"
)
// SubConfig 配置信息
type SubConfig struct {
PoolCacheSize int64 `json:"poolCacheSize"`
ProperFee int64 `json:"properFee"`
......
......@@ -13,7 +13,7 @@ import (
)
func TestNewMempool(t *testing.T) {
sub, _ := json.Marshal(&subConfig{PoolCacheSize: 2})
sub, _ := json.Marshal(&mempool.SubConfig{PoolCacheSize: 2})
module := New(&types.Mempool{}, sub)
mem := module.(*mempool.Mempool)
mem.Close()
......
......@@ -80,7 +80,11 @@ type TreeARC struct {
// NewTreeARC new lru mem tree
func NewTreeARC(size int) *TreeARC {
ma := &TreeARC{}
ma.arcCache, _ = lru.NewARC(size)
var err error
ma.arcCache, err = lru.NewARC(size)
if err != nil {
panic("New tree lru fail")
}
return ma
}
......
......@@ -256,22 +256,28 @@ func pruningFirstLevelNode(db dbm.DB, curHeight int64) {
}
func addLeafCountKeyToSecondLevel(db dbm.DB, kvs []*types.KeyValue, batch dbm.Batch) {
var err error
batch.Reset()
for _, kv := range kvs {
batch.Delete(kv.Key)
batch.Set(genOldLeafCountKeyFromKey(kv.Key), kv.Value)
if batch.ValueSize() > batchDataSize {
batch.Write()
if err = batch.Write(); err != nil {
return
}
batch.Reset()
}
}
batch.Write()
if err = batch.Write(); err != nil {
return
}
}
func deleteNode(db dbm.DB, mp map[string][]hashData, curHeight int64, batch dbm.Batch) {
if len(mp) == 0 {
return
}
var err error
batch.Reset()
for key, vals := range mp {
if len(vals) > 1 && vals[1].height != vals[0].height { //防止相同高度时候出现的误删除
......@@ -291,7 +297,9 @@ func deleteNode(db dbm.DB, mp map[string][]hashData, curHeight int64, batch dbm.
batch.Delete(leafCountKey) // 叶子计数节点
batch.Delete(val.hash) // 叶子节点hash值
if batch.ValueSize() > batchDataSize {
batch.Write()
if err = batch.Write(); err != nil {
return
}
batch.Reset()
}
}
......@@ -299,7 +307,9 @@ func deleteNode(db dbm.DB, mp map[string][]hashData, curHeight int64, batch dbm.
}
delete(mp, key)
}
batch.Write()
if err = batch.Write(); err != nil {
return
}
}
func pruningSecondLevel(db dbm.DB, curHeight int64) {
......@@ -313,7 +323,10 @@ func pruningSecondLevel(db dbm.DB, curHeight int64) {
pruningSecondLevelNode(db, curHeight)
end := time.Now()
treelog.Info("pruningTree pruningSecondLevel", "curHeight:", curHeight, "pruning leafNode cost time:", end.Sub(start))
setSecLvlPruningHeight(db, curHeight)
err := setSecLvlPruningHeight(db, curHeight)
if err != nil {
return
}
secLvlPruningH = curHeight
}
}
......@@ -363,6 +376,7 @@ func deleteOldNode(db dbm.DB, mp map[string][]hashData, curHeight int64, batch d
if len(mp) == 0 {
return
}
var err error
batch.Reset()
for key, vals := range mp {
if len(vals) > 1 {
......@@ -397,11 +411,15 @@ func deleteOldNode(db dbm.DB, mp map[string][]hashData, curHeight int64, batch d
}
delete(mp, key)
if batch.ValueSize() > batchDataSize {
batch.Write()
if err = batch.Write(); err != nil {
return
}
batch.Reset()
}
}
batch.Write()
if err = batch.Write(); err != nil {
return
}
}
// PruningTreePrintDB pruning tree print db
......
......@@ -179,13 +179,19 @@ func (t *Tree) Save() []byte {
if t.ndb != nil {
if t.isRemoveLeafCountKey() {
//DelLeafCountKV 需要先提前将leafcoutkey删除,这里需先于t.ndb.Commit()
DelLeafCountKV(t.ndb.db, t.blockHeight)
err := DelLeafCountKV(t.ndb.db, t.blockHeight)
if err != nil {
treelog.Error("Tree.Save", "DelLeafCountKV err", err)
}
}
saveNodeNo := t.root.save(t)
treelog.Debug("Tree.Save", "saveNodeNo", saveNodeNo, "tree height", t.blockHeight)
// 保存每个高度的roothash
if enablePrune {
t.root.saveRootHash(t)
err := t.root.saveRootHash(t)
if err != nil {
treelog.Error("Tree.Save", "saveRootHash err", err)
}
}
// 更新memTree
if enableMemTree && memTree != nil {
......@@ -335,7 +341,10 @@ func (t *Tree) isRemoveLeafCountKey() bool {
maxBlockHeight = t.getMaxBlockHeight()
}
if t.blockHeight > maxBlockHeight {
t.setMaxBlockHeight(t.blockHeight)
err := t.setMaxBlockHeight(t.blockHeight)
if err != nil {
panic(err)
}
maxBlockHeight = t.blockHeight
return false
}
......@@ -370,7 +379,9 @@ func (t *Tree) RemoveLeafCountKey(height int64) {
treelog.Debug("RemoveLeafCountKey:", "height", height, "key:", string(k), "hash:", common.ToHex(hash))
}
}
batch.Write()
if err := batch.Write(); err != nil {
return
}
}
// Iterate 依次迭代遍历树的所有键
......@@ -749,7 +760,10 @@ func VerifyKVPairProof(db dbm.DB, roothash []byte, keyvalue types.KeyValue, proo
// PrintTreeLeaf 通过roothash打印所有叶子节点
func PrintTreeLeaf(db dbm.DB, roothash []byte) {
tree := NewTree(db, true)
tree.Load(roothash)
err := tree.Load(roothash)
if err != nil {
return
}
var i int32
if tree.root != nil {
leafs := tree.root.size
......@@ -764,7 +778,10 @@ func PrintTreeLeaf(db dbm.DB, roothash []byte) {
// IterateRangeByStateHash 在start和end之间的键进行迭代回调[start, end)
func IterateRangeByStateHash(db dbm.DB, statehash, start, end []byte, ascending bool, fn func([]byte, []byte) bool) {
tree := NewTree(db, true)
tree.Load(statehash)
err := tree.Load(statehash)
if err != nil {
return
}
//treelog.Debug("IterateRangeByStateHash", "statehash", hex.EncodeToString(statehash), "start", string(start), "end", string(end))
tree.IterateRange(start, end, ascending, fn)
......
......@@ -672,8 +672,8 @@ func (_m *Chain33Client) GetLastHeader(ctx context.Context, in *types.ReqNil, op
return r0, r1
}
// GetProperFee provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetProperFee(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.ReplyProperFee, error) {
// GetLastMemPool provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetLastMemPool(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.ReplyTxList, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
......@@ -683,12 +683,12 @@ func (_m *Chain33Client) GetProperFee(ctx context.Context, in *types.ReqNil, opt
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *types.ReplyProperFee
if rf, ok := ret.Get(0).(func(context.Context, *types.ReqNil, ...grpc.CallOption) *types.ReplyProperFee); ok {
var r0 *types.ReplyTxList
if rf, ok := ret.Get(0).(func(context.Context, *types.ReqNil, ...grpc.CallOption) *types.ReplyTxList); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ReplyProperFee)
r0 = ret.Get(0).(*types.ReplyTxList)
}
}
......@@ -702,8 +702,8 @@ func (_m *Chain33Client) GetProperFee(ctx context.Context, in *types.ReqNil, opt
return r0, r1
}
// GetLastMemPool provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetLastMemPool(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.ReplyTxList, error) {
// GetMemPool provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetMemPool(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.ReplyTxList, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
......@@ -732,8 +732,8 @@ func (_m *Chain33Client) GetLastMemPool(ctx context.Context, in *types.ReqNil, o
return r0, r1
}
// GetMemPool provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetMemPool(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.ReplyTxList, error) {
// GetPeerInfo provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetPeerInfo(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.PeerList, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
......@@ -743,12 +743,12 @@ func (_m *Chain33Client) GetMemPool(ctx context.Context, in *types.ReqNil, opts
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *types.ReplyTxList
if rf, ok := ret.Get(0).(func(context.Context, *types.ReqNil, ...grpc.CallOption) *types.ReplyTxList); ok {
var r0 *types.PeerList
if rf, ok := ret.Get(0).(func(context.Context, *types.ReqNil, ...grpc.CallOption) *types.PeerList); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ReplyTxList)
r0 = ret.Get(0).(*types.PeerList)
}
}
......@@ -762,8 +762,8 @@ func (_m *Chain33Client) GetMemPool(ctx context.Context, in *types.ReqNil, opts
return r0, r1
}
// GetPeerInfo provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetPeerInfo(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.PeerList, error) {
// GetProperFee provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetProperFee(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.ReplyProperFee, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
......@@ -773,12 +773,12 @@ func (_m *Chain33Client) GetPeerInfo(ctx context.Context, in *types.ReqNil, opts
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *types.PeerList
if rf, ok := ret.Get(0).(func(context.Context, *types.ReqNil, ...grpc.CallOption) *types.PeerList); ok {
var r0 *types.ReplyProperFee
if rf, ok := ret.Get(0).(func(context.Context, *types.ReqNil, ...grpc.CallOption) *types.ReplyProperFee); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.PeerList)
r0 = ret.Get(0).(*types.ReplyProperFee)
}
}
......
......@@ -6,9 +6,10 @@ package types
import (
context "context"
fmt "fmt"
math "math"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
......
......@@ -5,8 +5,9 @@ package types
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
proto "github.com/golang/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
......
......@@ -65,12 +65,21 @@ func RunChain33(name string) {
*configPath = name + ".toml"
}
}
d, _ := os.Getwd()
d, err := os.Getwd()
if err != nil {
panic(err)
}
log.Info("current dir:", "dir", d)
os.Chdir(pwd())
d, _ = os.Getwd()
err = os.Chdir(pwd())
if err != nil {
panic(err)
}
d, err = os.Getwd()
if err != nil {
panic(err)
}
log.Info("current dir:", "dir", d)
err := limits.SetLimits()
err = limits.SetLimits()
if err != nil {
panic(err)
}
......@@ -109,9 +118,15 @@ func RunChain33(name string) {
//set pprof
go func() {
if cfg.Pprof != nil {
http.ListenAndServe(cfg.Pprof.ListenAddr, nil)
err := http.ListenAndServe(cfg.Pprof.ListenAddr, nil)
if err != nil {
log.Info("ListenAndServe", "listen addr", cfg.Pprof.ListenAddr, "err", err)
}
} else {
http.ListenAndServe("localhost:6060", nil)
err := http.ListenAndServe("localhost:6060", nil)
if err != nil {
log.Info("ListenAndServe", "listen addr localhost:6060 err", err)
}
}
}()
//set maxprocs
......
......@@ -34,7 +34,10 @@ var closeCmd = &cobra.Command{
Use: "close",
Short: "Close " + types.GetTitle(),
Run: func(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
rpcLaddr, err := cmd.Flags().GetString("rpc_laddr")
if err != nil {
panic(err)
}
// rpc, _ := jsonrpc.NewJSONClient(rpcLaddr)
// rpc.Call("Chain33.CloseQueue", nil, nil)
var res rpctypes.Reply
......
......@@ -163,7 +163,11 @@ func CheckTxDup(client queue.Client, txs []*types.TransactionCache, height int64
}
checkHashList.Count = height
hashList := client.NewMessage("blockchain", types.EventTxHashList, &checkHashList)
client.Send(hashList, true)
err = client.Send(hashList, true)
if err != nil {
log.Error("send", "to blockchain EventTxHashList msg err", err)
return nil, err
}
dupTxList, err := client.Wait(hashList)
if err != nil {
return nil, err
......@@ -199,7 +203,10 @@ func ReportErrEventToFront(logger log.Logger, client queue.Client, frommodule st
reportErrEvent.Tomodule = tomodule
reportErrEvent.Error = err.Error()
msg := client.NewMessage(tomodule, types.EventErrToFront, &reportErrEvent)
client.Send(msg, false)
err = client.Send(msg, false)
if err != nil {
log.Error("send", "EventErrToFront msg err", err)
}
}
//DelDupKey 删除重复的key
......
This diff is collapsed.
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