Commit a4a6b8fa authored by 张振华's avatar 张振华

Merge branch 'master' into guess

parents 1123e1d5 dc3ab81f
...@@ -46,7 +46,7 @@ go_test: ...@@ -46,7 +46,7 @@ go_test:
tags: tags:
- 33cn - 33cn
script: script:
- make docker-compose-down DAPP=all - make docker-compose-down dapp=all
- make test - make test
only: only:
- master - master
...@@ -90,8 +90,8 @@ deploy_relay: ...@@ -90,8 +90,8 @@ deploy_relay:
- 33cn - 33cn
script: script:
- make build_ci - make build_ci
- make docker-compose PROJ=relay DAPP=relay - make docker-compose proj=relay dapp=relay
- make docker-compose-down PROJ=relay DAPP=relay - make docker-compose-down proj=relay dapp=relay
only: only:
- master - master
...@@ -101,8 +101,8 @@ deploy_paracross: ...@@ -101,8 +101,8 @@ deploy_paracross:
- 33cn - 33cn
script: script:
- make build_ci - make build_ci
- make docker-compose PROJ=paracross DAPP=paracross - make docker-compose proj=paracross dapp=paracross
- make docker-compose-down PROJ=paracross DAPP=paracross - make docker-compose-down proj=paracross dapp=paracross
only: only:
- master - master
...@@ -139,8 +139,8 @@ fork_test_privacy: ...@@ -139,8 +139,8 @@ fork_test_privacy:
script: script:
- if [ -n "${onceEveryday}" ]; then - if [ -n "${onceEveryday}" ]; then
- make build_ci - make build_ci
- make fork-test PROJ=privacy DAPP=privacy - make fork-test proj=privacy dapp=privacy
- make docker-compose-down PROJ=privacy DAPP=privacy - make docker-compose-down proj=privacy dapp=privacy
- fi - fi
only: only:
- master - master
...@@ -153,8 +153,8 @@ fork_test_paracross: ...@@ -153,8 +153,8 @@ fork_test_paracross:
script: script:
- if [ -n "${onceEveryday}" ]; then - if [ -n "${onceEveryday}" ]; then
- make build_ci - make build_ci
- make fork-test PROJ=paracross DAPP=paracross - make fork-test proj=paracross dapp=paracross
- make docker-compose-down PROJ=paracross DAPP=paracross - make docker-compose-down proj=paracross dapp=paracross
- fi - fi
only: only:
- master - master
...@@ -168,8 +168,8 @@ fork_test_all: ...@@ -168,8 +168,8 @@ fork_test_all:
script: script:
- if [ -n "${onceEveryday}" ]; then - if [ -n "${onceEveryday}" ]; then
- make build_ci - make build_ci
- make fork-test PROJ=fork DAPP=all - make fork-test proj=fork dapp=all
- make docker-compose-down PROJ=fork DAPP=all - make docker-compose-down proj=fork dapp=all
- fi - fi
only: only:
- master - master
...@@ -183,8 +183,8 @@ deploy_test_all: ...@@ -183,8 +183,8 @@ deploy_test_all:
script: script:
- if [ -n "${onceEveryday}" ]; then - if [ -n "${onceEveryday}" ]; then
- make build_ci - make build_ci
- make docker-compose PROJ=deploy DAPP=all - make docker-compose proj=deploy dapp=all
- make docker-compose-down PROJ=deploy DAPP=all - make docker-compose-down proj=deploy dapp=all
- fi - fi
only: only:
- master - master
......
...@@ -62,4 +62,4 @@ matrix: ...@@ -62,4 +62,4 @@ matrix:
- sudo mv docker-compose /usr/local/bin - sudo mv docker-compose /usr/local/bin
before_script: make build_ci before_script: make build_ci
script: script:
- make docker-compose DAPP=${DAPP} && make docker-compose-down DAPP=${DAPP} && make clean - make docker-compose dapp=${DAPP} && make docker-compose-down dapp=${DAPP} && make clean
...@@ -17,8 +17,7 @@ PKG_LIST_INEFFASSIGN= `go list -f {{.Dir}} ./... | grep -v "vendor"` ...@@ -17,8 +17,7 @@ PKG_LIST_INEFFASSIGN= `go list -f {{.Dir}} ./... | grep -v "vendor"`
BUILD_FLAGS = -ldflags "-X github.com/33cn/chain33/common/version.GitCommit=`git rev-parse --short=8 HEAD`" BUILD_FLAGS = -ldflags "-X github.com/33cn/chain33/common/version.GitCommit=`git rev-parse --short=8 HEAD`"
MKPATH=$(abspath $(lastword $(MAKEFILE_LIST))) MKPATH=$(abspath $(lastword $(MAKEFILE_LIST)))
MKDIR=$(dir $(MKPATH)) MKDIR=$(dir $(MKPATH))
DAPP := "" proj := "build"
PROJ := "build"
.PHONY: default dep all build release cli linter race test fmt vet bench msan coverage coverhtml docker docker-compose protobuf clean help autotest .PHONY: default dep all build release cli linter race test fmt vet bench msan coverage coverhtml docker docker-compose protobuf clean help autotest
default: build depends default: build depends
...@@ -123,16 +122,16 @@ docker-compose: ## build docker-compose for chain33 run ...@@ -123,16 +122,16 @@ docker-compose: ## build docker-compose for chain33 run
@cd build && if ! [ -d ci ]; then \ @cd build && if ! [ -d ci ]; then \
make -C ../ ; \ make -C ../ ; \
fi; \ fi; \
cp chain33* Dockerfile docker-compose* ci/ && cd ci/ && ./docker-compose-pre.sh run $(PROJ) $(DAPP) && cd ../.. cp chain33* Dockerfile docker-compose* ci/ && cd ci/ && ./docker-compose-pre.sh run $(proj) $(dapp) && cd ../..
docker-compose-down: ## build docker-compose for chain33 run docker-compose-down: ## build docker-compose for chain33 run
@cd build && if [ -d ci ]; then \ @cd build && if [ -d ci ]; then \
cp chain33* Dockerfile docker-compose* ci/ && cd ci/ && ./docker-compose-pre.sh down $(PROJ) $(DAPP) && cd .. ; \ cp chain33* Dockerfile docker-compose* ci/ && cd ci/ && ./docker-compose-pre.sh down $(proj) $(dapp) && cd .. ; \
fi; \ fi; \
cd .. cd ..
fork-test: ## build fork-test for chain33 run fork-test: ## build fork-test for chain33 run
@cd build && cp chain33* Dockerfile system-fork-test.sh docker-compose* ci/ && cd ci/ && ./docker-compose-pre.sh forktest $(PROJ) $(DAPP) && cd ../.. @cd build && cp chain33* Dockerfile system-fork-test.sh docker-compose* ci/ && cd ci/ && ./docker-compose-pre.sh forktest $(proj) $(dapp) && cd ../..
clean: ## Remove previous build clean: ## Remove previous build
......
...@@ -68,24 +68,37 @@ type client struct { ...@@ -68,24 +68,37 @@ type client struct {
wg sync.WaitGroup wg sync.WaitGroup
} }
type subConfig struct {
WriteBlockSeconds int64 `json:"writeBlockSeconds,omitempty"`
ParaRemoteGrpcClient string `json:"paraRemoteGrpcClient,omitempty"`
StartHeight int64 `json:"startHeight,omitempty"`
EmptyBlockInterval int64 `json:"emptyBlockInterval,omitempty"`
AuthAccount string `json:"authAccount,omitempty"`
WaitBlocks4CommitMsg int32 `json:"waitBlocks4CommitMsg,omitempty"`
SearchHashMatchedBlockDepth int32 `json:"searchHashMatchedBlockDepth,omitempty"`
}
// New function to init paracross env // New function to init paracross env
func New(cfg *types.Consensus, sub []byte) queue.Module { func New(cfg *types.Consensus, sub []byte) queue.Module {
c := drivers.NewBaseClient(cfg) c := drivers.NewBaseClient(cfg)
if cfg.ParaRemoteGrpcClient != "" { var subcfg subConfig
grpcSite = cfg.ParaRemoteGrpcClient if sub != nil {
types.MustDecode(sub, &subcfg)
} }
if cfg.StartHeight > 0 { if subcfg.ParaRemoteGrpcClient != "" {
startHeight = cfg.StartHeight grpcSite = subcfg.ParaRemoteGrpcClient
} }
if cfg.WriteBlockSeconds > 0 { if subcfg.StartHeight > 0 {
blockSec = cfg.WriteBlockSeconds startHeight = subcfg.StartHeight
} }
if cfg.EmptyBlockInterval > 0 { if subcfg.WriteBlockSeconds > 0 {
emptyBlockInterval = cfg.EmptyBlockInterval blockSec = subcfg.WriteBlockSeconds
} }
if subcfg.EmptyBlockInterval > 0 {
if cfg.SearchHashMatchedBlockDepth > 0 { emptyBlockInterval = subcfg.EmptyBlockInterval
searchHashMatchDepth = cfg.SearchHashMatchedBlockDepth }
if subcfg.SearchHashMatchedBlockDepth > 0 {
searchHashMatchDepth = subcfg.SearchHashMatchedBlockDepth
} }
pk, err := hex.DecodeString(minerPrivateKey) pk, err := hex.DecodeString(minerPrivateKey)
...@@ -117,25 +130,22 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -117,25 +130,22 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
conn: conn, conn: conn,
grpcClient: grpcClient, grpcClient: grpcClient,
paraClient: paraCli, paraClient: paraCli,
authAccount: cfg.AuthAccount, authAccount: subcfg.AuthAccount,
privateKey: priKey, privateKey: priKey,
isCaughtUp: false, isCaughtUp: false,
} }
if subcfg.WaitBlocks4CommitMsg < 2 {
if cfg.WaitBlocks4CommitMsg < 2 {
panic("config WaitBlocks4CommitMsg should not less 2") panic("config WaitBlocks4CommitMsg should not less 2")
} }
para.commitMsgClient = &commitMsgClient{ para.commitMsgClient = &commitMsgClient{
paraClient: para, paraClient: para,
waitMainBlocks: cfg.WaitBlocks4CommitMsg, waitMainBlocks: subcfg.WaitBlocks4CommitMsg,
commitMsgNotify: make(chan int64, 1), commitMsgNotify: make(chan int64, 1),
delMsgNotify: make(chan int64, 1), delMsgNotify: make(chan int64, 1),
mainBlockAdd: make(chan *types.BlockDetail, 1), mainBlockAdd: make(chan *types.BlockDetail, 1),
quit: make(chan struct{}), quit: make(chan struct{}),
} }
c.SetChild(para) c.SetChild(para)
return para return para
} }
...@@ -178,6 +188,7 @@ func (client *client) InitBlock() { ...@@ -178,6 +188,7 @@ func (client *client) InitBlock() {
newblock.Height = 0 newblock.Height = 0
newblock.BlockTime = genesisBlockTime newblock.BlockTime = genesisBlockTime
newblock.ParentHash = zeroHash[:] newblock.ParentHash = zeroHash[:]
newblock.MainHash = zeroHash[:]
tx := client.CreateGenesisTx() tx := client.CreateGenesisTx()
newblock.Txs = tx newblock.Txs = tx
newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs) newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs)
...@@ -661,16 +672,13 @@ func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main * ...@@ -661,16 +672,13 @@ func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main *
MainBlockHash: main.Seq.Hash, MainBlockHash: main.Seq.Hash,
MainBlockHeight: main.Detail.Block.Height, MainBlockHeight: main.Detail.Block.Height,
} }
tx, err := paracross.CreateRawMinerTx(status) tx, err := paracross.CreateRawMinerTx(status)
if err != nil { if err != nil {
return err return err
} }
tx.Sign(types.SECP256K1, client.privateKey) tx.Sign(types.SECP256K1, client.privateKey)
block.Txs = append([]*types.Transaction{tx}, block.Txs...) block.Txs = append([]*types.Transaction{tx}, block.Txs...)
return nil return nil
} }
func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transaction, seq int64, mainBlock *types.BlockSeq) error { func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transaction, seq int64, mainBlock *types.BlockSeq) error {
...@@ -683,7 +691,8 @@ func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transacti ...@@ -683,7 +691,8 @@ func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transacti
newblock.Difficulty = types.GetP(0).PowLimitBits newblock.Difficulty = types.GetP(0).PowLimitBits
newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs) newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs)
newblock.BlockTime = mainBlock.Detail.Block.BlockTime newblock.BlockTime = mainBlock.Detail.Block.BlockTime
newblock.MainHash = mainBlock.Detail.Block.Hash()
newblock.MainHeight = mainBlock.Detail.Block.Height
err := client.addMinerTx(lastBlock.StateHash, &newblock, mainBlock) err := client.addMinerTx(lastBlock.StateHash, &newblock, mainBlock)
if err != nil { if err != nil {
return err return err
......
...@@ -60,7 +60,10 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu ...@@ -60,7 +60,10 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu
q := queue.New("channel") q := queue.New("channel")
s.q = q s.q = q
//api, _ = client.New(q.Client(), nil) //api, _ = client.New(q.Client(), nil)
var subcfg subConfig
if sub != nil {
types.MustDecode(sub.Consensus["para"], &subcfg)
}
s.block = blockchain.New(cfg.BlockChain) s.block = blockchain.New(cfg.BlockChain)
s.block.SetQueueClient(q.Client()) s.block.SetQueueClient(q.Client())
...@@ -83,9 +86,9 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu ...@@ -83,9 +86,9 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu
ret := &types.Reply{IsOk: true, Msg: data} ret := &types.Reply{IsOk: true, Msg: data}
s.grpcCli.On("QueryChain", mock.Anything, mock.Anything).Return(ret, nil).Maybe() s.grpcCli.On("QueryChain", mock.Anything, mock.Anything).Return(ret, nil).Maybe()
s.grpcCli.On("SendTransaction", mock.Anything, mock.Anything).Return(reply, nil).Maybe() s.grpcCli.On("SendTransaction", mock.Anything, mock.Anything).Return(reply, nil).Maybe()
s.grpcCli.On("GetLastHeader", mock.Anything, mock.Anything).Return(&types.Header{Height: cfg.Consensus.StartHeight + minBlockNum}, nil).Maybe() s.grpcCli.On("GetLastHeader", mock.Anything, mock.Anything).Return(&types.Header{Height: subcfg.StartHeight + minBlockNum}, nil).Maybe()
s.grpcCli.On("GetBlockHash", mock.Anything, mock.Anything).Return(&types.ReplyHash{Hash: []byte("1")}, nil).Maybe() s.grpcCli.On("GetBlockHash", mock.Anything, mock.Anything).Return(&types.ReplyHash{Hash: []byte("1")}, nil).Maybe()
s.grpcCli.On("GetSequenceByHash", mock.Anything, mock.Anything).Return(&types.Int64{Data: cfg.Consensus.StartHeight}, nil).Maybe() s.grpcCli.On("GetSequenceByHash", mock.Anything, mock.Anything).Return(&types.Int64{Data: subcfg.StartHeight}, nil).Maybe()
s.para.grpcClient = s.grpcCli s.para.grpcClient = s.grpcCli
s.para.SetQueueClient(q.Client()) s.para.SetQueueClient(q.Client())
......
...@@ -46,7 +46,10 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule) ...@@ -46,7 +46,10 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule)
q := queue.New("channel") q := queue.New("channel")
s.q = q s.q = q
//api, _ = client.New(q.Client(), nil) //api, _ = client.New(q.Client(), nil)
var subcfg subConfig
if sub != nil {
types.MustDecode(sub.Consensus["para"], &subcfg)
}
s.block = blockchain.New(cfg.BlockChain) s.block = blockchain.New(cfg.BlockChain)
s.block.SetQueueClient(q.Client()) s.block.SetQueueClient(q.Client())
...@@ -58,7 +61,7 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule) ...@@ -58,7 +61,7 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule)
//cfg.Consensus.StartHeight = 0 //cfg.Consensus.StartHeight = 0
//add block by UT below //add block by UT below
cfg.Consensus.EmptyBlockInterval = 100 subcfg.EmptyBlockInterval = 100
s.para = New(cfg.Consensus, sub.Consensus["para"]).(*client) s.para = New(cfg.Consensus, sub.Consensus["para"]).(*client)
s.grpcCli = &typesmocks.Chain33Client{} s.grpcCli = &typesmocks.Chain33Client{}
...@@ -72,7 +75,7 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule) ...@@ -72,7 +75,7 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule)
ret := &types.Reply{IsOk: true, Msg: data} ret := &types.Reply{IsOk: true, Msg: data}
s.grpcCli.On("QueryChain", mock.Anything, mock.Anything).Return(ret, nil).Maybe() s.grpcCli.On("QueryChain", mock.Anything, mock.Anything).Return(ret, nil).Maybe()
s.grpcCli.On("SendTransaction", mock.Anything, mock.Anything).Return(reply, nil).Maybe() s.grpcCli.On("SendTransaction", mock.Anything, mock.Anything).Return(reply, nil).Maybe()
s.grpcCli.On("GetLastHeader", mock.Anything, mock.Anything).Return(&types.Header{Height: cfg.Consensus.StartHeight + minBlockNum}, nil).Maybe() s.grpcCli.On("GetLastHeader", mock.Anything, mock.Anything).Return(&types.Header{Height: subcfg.StartHeight + minBlockNum}, nil).Maybe()
s.grpcCli.On("GetBlockHash", mock.Anything, mock.Anything).Return(&types.ReplyHash{Hash: []byte("1")}, nil).Maybe() s.grpcCli.On("GetBlockHash", mock.Anything, mock.Anything).Return(&types.ReplyHash{Hash: []byte("1")}, nil).Maybe()
s.para.grpcClient = s.grpcCli s.para.grpcClient = s.grpcCli
s.para.SetQueueClient(q.Client()) s.para.SetQueueClient(q.Client())
......
...@@ -46,7 +46,6 @@ func NewRaftCluster(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -46,7 +46,6 @@ func NewRaftCluster(cfg *types.Consensus, sub []byte) queue.Module {
if sub != nil { if sub != nil {
types.MustDecode(sub, &subcfg) types.MustDecode(sub, &subcfg)
} }
if subcfg.Genesis != "" { if subcfg.Genesis != "" {
genesis = subcfg.Genesis genesis = subcfg.Genesis
} }
......
...@@ -12,7 +12,6 @@ import ( ...@@ -12,7 +12,6 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
"time" "time"
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
......
...@@ -413,12 +413,16 @@ kvcreator.prototype.receipt = function() { ...@@ -413,12 +413,16 @@ kvcreator.prototype.receipt = function() {
function GetExecName() { function GetExecName() {
var exec = execname() var exec = execname()
if (exec.err) { throwerr(exec.err)
return ""
}
return exec.value return exec.value
} }
function GetRandnum() {
var n = randnum()
throwerr(n.err)
return n.value
}
function ExecAddress(name) { function ExecAddress(name) {
var addr = execaddress(name) var addr = execaddress(name)
if (addr.err) { if (addr.err) {
...@@ -521,6 +525,7 @@ function Init(context) { ...@@ -521,6 +525,7 @@ function Init(context) {
this.context = context this.context = context
this.kvc.add("action", "init") this.kvc.add("action", "init")
this.kvc.add("context", this.context) this.kvc.add("context", this.context)
this.kvc.add("randnum", GetRandnum())
return this.kvc.receipt() return this.kvc.receipt()
} }
......
...@@ -7,6 +7,7 @@ function Init(context) { ...@@ -7,6 +7,7 @@ function Init(context) {
this.context = context this.context = context
this.kvc.add("action", "init") this.kvc.add("action", "init")
this.kvc.add("context", this.context) this.kvc.add("context", this.context)
this.kvc.add("randnum", GetRandnum())
return this.kvc.receipt() return this.kvc.receipt()
} }
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"github.com/33cn/chain33/client/api"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
drivers "github.com/33cn/chain33/system/dapp" drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
...@@ -114,6 +115,9 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction, ...@@ -114,6 +115,9 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction,
vm.Set("args", payload.Args) vm.Set("args", payload.Args)
callfunc := "callcode(context, f, args, loglist)" callfunc := "callcode(context, f, args, loglist)"
jsvalue, err := vm.Run(callfunc) jsvalue, err := vm.Run(callfunc)
if u.GetExecutorAPI().IsErr() {
return nil, api.ErrAPIEnv
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -229,6 +233,22 @@ func (u *js) execnameFunc(vm *otto.Otto, name string) { ...@@ -229,6 +233,22 @@ func (u *js) execnameFunc(vm *otto.Otto, name string) {
}) })
} }
func (u *js) randnumFunc(vm *otto.Otto, name string) {
vm.Set("randnum", func(call otto.FunctionCall) otto.Value {
hash := u.GetLastHash()
param := &types.ReqRandHash{
ExecName: "ticket",
BlockNum: 5,
Hash: hash,
}
randhash, err := u.GetExecutorAPI().GetRandNum(param)
if err != nil {
return errReturn(vm, err)
}
return okReturn(vm, common.ToHex(randhash))
})
}
func (u *js) listdbFunc(vm *otto.Otto, name string) { func (u *js) listdbFunc(vm *otto.Otto, name string) {
//List(prefix, key []byte, count, direction int32) ([][]byte, error) //List(prefix, key []byte, count, direction int32) ([][]byte, error)
_, plocal := calcAllPrefix(name) _, plocal := calcAllPrefix(name)
...@@ -281,6 +301,7 @@ func (u *js) createVM(name string, tx *types.Transaction, index int) (*otto.Otto ...@@ -281,6 +301,7 @@ func (u *js) createVM(name string, tx *types.Transaction, index int) (*otto.Otto
u.localdbFunc(vm, name) u.localdbFunc(vm, name)
u.listdbFunc(vm, name) u.listdbFunc(vm, name)
u.execnameFunc(vm, name) u.execnameFunc(vm, name)
u.randnumFunc(vm, name)
u.registerAccountFunc(vm) u.registerAccountFunc(vm)
u.registerTableFunc(vm, name) u.registerTableFunc(vm, name)
return vm, nil return vm, nil
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common/db" "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util" "github.com/33cn/chain33/util"
...@@ -16,6 +17,7 @@ import ( ...@@ -16,6 +17,7 @@ import (
"github.com/33cn/plugin/plugin/dapp/js/types/jsproto" "github.com/33cn/plugin/plugin/dapp/js/types/jsproto"
"github.com/robertkrimen/otto" "github.com/robertkrimen/otto"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
) )
func init() { func init() {
...@@ -25,6 +27,9 @@ func init() { ...@@ -25,6 +27,9 @@ func init() {
func initExec(ldb db.DB, kvdb db.KVDB, code string, t assert.TestingT) *js { func initExec(ldb db.DB, kvdb db.KVDB, code string, t assert.TestingT) *js {
e := newjs().(*js) e := newjs().(*js)
e.SetEnv(1, time.Now().Unix(), 1) e.SetEnv(1, time.Now().Unix(), 1)
mockapi := &mocks.QueueProtocolAPI{}
mockapi.On("Query", "ticket", "RandNumHash", mock.Anything).Return(&types.ReplyHash{Hash: []byte("hello")}, nil)
e.SetAPI(mockapi)
e.SetLocalDB(kvdb) e.SetLocalDB(kvdb)
e.SetStateDB(kvdb) e.SetStateDB(kvdb)
c, tx := createCodeTx("test", code) c, tx := createCodeTx("test", code)
...@@ -187,8 +192,9 @@ func TestCacheMemUsage(t *testing.T) { ...@@ -187,8 +192,9 @@ func TestCacheMemUsage(t *testing.T) {
e := initExec(ldb, kvdb, jscode, t) e := initExec(ldb, kvdb, jscode, t)
vm, err := e.createVM("test", nil, 0) vm, err := e.createVM("test", nil, 0)
assert.Nil(t, err) assert.Nil(t, err)
vms := make([]*otto.Otto, 1024) n := 64
for i := 0; i < 1024; i++ { vms := make([]*otto.Otto, n)
for i := 0; i < n; i++ {
vms[i] = vm.Copy() vms[i] = vm.Copy()
} }
printMemUsage() printMemUsage()
......
...@@ -25,7 +25,9 @@ func init() { ...@@ -25,7 +25,9 @@ func init() {
} }
func TestJsVM(t *testing.T) { func TestJsVM(t *testing.T) {
mocker := testnode.New("--free--", nil) cfg, sub := testnode.GetDefaultConfig()
cfg.Consensus.Name = "ticket"
mocker := testnode.NewWithConfig(cfg, sub, nil)
defer mocker.Close() defer mocker.Close()
mocker.Listen() mocker.Listen()
//开始部署合约, 测试阶段任何人都可以部署合约 //开始部署合约, 测试阶段任何人都可以部署合约
......
...@@ -410,12 +410,16 @@ kvcreator.prototype.receipt = function() { ...@@ -410,12 +410,16 @@ kvcreator.prototype.receipt = function() {
function GetExecName() { function GetExecName() {
var exec = execname() var exec = execname()
if (exec.err) { throwerr(exec.err)
return ""
}
return exec.value return exec.value
} }
function GetRandnum() {
var n = randnum()
throwerr(n.err)
return n.value
}
function ExecAddress(name) { function ExecAddress(name) {
var addr = execaddress(name) var addr = execaddress(name)
if (addr.err) { if (addr.err) {
......
...@@ -4,6 +4,7 @@ function Init(context) { ...@@ -4,6 +4,7 @@ function Init(context) {
this.context = context this.context = context
this.kvc.add("action", "init") this.kvc.add("action", "init")
this.kvc.add("context", this.context) this.kvc.add("context", this.context)
this.kvc.add("randnum", GetRandnum())
return this.kvc.receipt() return this.kvc.receipt()
} }
......
// 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 (
"context"
"time"
"github.com/33cn/chain33/types"
)
const retryNum = 10
// GetMainHeightByTxHash get Block height
func (action *Action) GetMainHeightByTxHash(txHash []byte) int64 {
for i := 0; i < retryNum; i++ {
req := &types.ReqHash{Hash: txHash}
txDetail, err := action.grpcClient.QueryTransaction(context.Background(), req)
if err != nil {
time.Sleep(time.Second)
} else {
return txDetail.GetHeight()
}
}
return -1
}
// GetMainBlockHashByHeight get Hash
func (action *Action) GetMainBlockHashByHeight(height int64) ([]byte, error) {
for i := 0; i < retryNum; i++ {
req := &types.ReqInt{Height: height}
replyHash, err := action.grpcClient.GetBlockHash(context.Background(), req)
if err != nil {
time.Sleep(time.Second)
} else {
return replyHash.Hash, nil
}
}
return nil, types.ErrBlockNotFound
}
...@@ -5,17 +5,14 @@ ...@@ -5,17 +5,14 @@
package executor package executor
import ( import (
"context"
"strconv" "strconv"
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp" "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
pty "github.com/33cn/plugin/plugin/dapp/lottery/types" pty "github.com/33cn/plugin/plugin/dapp/lottery/types"
"google.golang.org/grpc"
) )
const ( const (
...@@ -53,9 +50,7 @@ const ( ...@@ -53,9 +50,7 @@ const (
const ( const (
luckyNumMol = 100000 luckyNumMol = 100000
decimal = 100000000 //1e8 decimal = 100000000 //1e8
//randMolNum = 5 blockNum = 5
grpcRecSize int = 5 * 30 * 1024 * 1024
blockNum = 5
) )
const ( const (
...@@ -123,9 +118,6 @@ type Action struct { ...@@ -123,9 +118,6 @@ type Action struct {
height int64 height int64
execaddr string execaddr string
difficulty uint64 difficulty uint64
api client.QueueProtocolAPI
conn *grpc.ClientConn
grpcClient types.Chain33Client
index int index int
lottery *Lottery lottery *Lottery
} }
...@@ -134,19 +126,11 @@ type Action struct { ...@@ -134,19 +126,11 @@ type Action struct {
func NewLotteryAction(l *Lottery, tx *types.Transaction, index int) *Action { func NewLotteryAction(l *Lottery, tx *types.Transaction, index int) *Action {
hash := tx.Hash() hash := tx.Hash()
fromaddr := tx.From() fromaddr := tx.From()
return &Action{
msgRecvOp := grpc.WithMaxMsgSize(grpcRecSize) coinsAccount: l.GetCoinsAccount(), db: l.GetStateDB(),
paraRemoteGrpcClient := types.Conf("config.consensus").GStr("ParaRemoteGrpcClient") txhash: hash, fromaddr: fromaddr, blocktime: l.GetBlockTime(),
height: l.GetHeight(), execaddr: dapp.ExecAddress(string(tx.Execer)),
conn, err := grpc.Dial(paraRemoteGrpcClient, grpc.WithInsecure(), msgRecvOp) difficulty: l.GetDifficulty(), index: index, lottery: l}
if err != nil {
panic(err)
}
grpcClient := types.NewChain33Client(conn)
return &Action{l.GetCoinsAccount(), l.GetStateDB(), hash, fromaddr, l.GetBlockTime(),
l.GetHeight(), dapp.ExecAddress(string(tx.Execer)), l.GetDifficulty(), l.GetAPI(), conn, grpcClient, index, l}
} }
// GetLottCommonRecipt generate logs for lottery common action // GetLottCommonRecipt generate logs for lottery common action
...@@ -275,12 +259,7 @@ func (action *Action) LotteryCreate(create *pty.LotteryCreate) (*types.Receipt, ...@@ -275,12 +259,7 @@ func (action *Action) LotteryCreate(create *pty.LotteryCreate) (*types.Receipt,
lott.BuyAmount = 0 lott.BuyAmount = 0
llog.Debug("LotteryCreate", "OpRewardRatio", lott.OpRewardRatio, "DevRewardRatio", lott.DevRewardRatio) llog.Debug("LotteryCreate", "OpRewardRatio", lott.OpRewardRatio, "DevRewardRatio", lott.DevRewardRatio)
if types.IsPara() { if types.IsPara() {
mainHeight := action.GetMainHeightByTxHash(action.txhash) lott.CreateOnMain = action.lottery.GetMainHeight()
if mainHeight < 0 {
llog.Error("LotteryCreate", "mainHeight", mainHeight)
return nil, pty.ErrLotteryStatus
}
lott.CreateOnMain = mainHeight
} }
llog.Debug("LotteryCreate created", "lotteryID", lotteryID) llog.Debug("LotteryCreate created", "lotteryID", lotteryID)
...@@ -330,22 +309,13 @@ func (action *Action) LotteryBuy(buy *pty.LotteryBuy) (*types.Receipt, error) { ...@@ -330,22 +309,13 @@ func (action *Action) LotteryBuy(buy *pty.LotteryBuy) (*types.Receipt, error) {
lott.Status = pty.LotteryPurchase lott.Status = pty.LotteryPurchase
lott.Round++ lott.Round++
if types.IsPara() { if types.IsPara() {
mainHeight := action.GetMainHeightByTxHash(action.txhash) lott.LastTransToPurStateOnMain = action.lottery.GetMainHeight()
if mainHeight < 0 {
llog.Error("LotteryBuy", "mainHeight", mainHeight)
return nil, pty.ErrLotteryStatus
}
lott.LastTransToPurStateOnMain = mainHeight
} }
} }
if lott.Status == pty.LotteryPurchase { if lott.Status == pty.LotteryPurchase {
if types.IsPara() { if types.IsPara() {
mainHeight := action.GetMainHeightByTxHash(action.txhash) mainHeight := action.lottery.GetMainHeight()
if mainHeight < 0 {
llog.Error("LotteryBuy", "mainHeight", mainHeight)
return nil, pty.ErrLotteryStatus
}
if mainHeight-lott.LastTransToPurStateOnMain > lott.GetPurBlockNum() { if mainHeight-lott.LastTransToPurStateOnMain > lott.GetPurBlockNum() {
llog.Error("LotteryBuy", "action.height", action.height, "mainHeight", mainHeight, "LastTransToPurStateOnMain", lott.LastTransToPurStateOnMain) llog.Error("LotteryBuy", "action.height", action.height, "mainHeight", mainHeight, "LastTransToPurStateOnMain", lott.LastTransToPurStateOnMain)
return nil, pty.ErrLotteryStatus return nil, pty.ErrLotteryStatus
...@@ -451,11 +421,7 @@ func (action *Action) LotteryDraw(draw *pty.LotteryDraw) (*types.Receipt, error) ...@@ -451,11 +421,7 @@ func (action *Action) LotteryDraw(draw *pty.LotteryDraw) (*types.Receipt, error)
} }
if types.IsPara() { if types.IsPara() {
mainHeight := action.GetMainHeightByTxHash(action.txhash) mainHeight := action.lottery.GetMainHeight()
if mainHeight < 0 {
llog.Error("LotteryBuy", "mainHeight", mainHeight)
return nil, pty.ErrLotteryStatus
}
if mainHeight-lott.GetLastTransToPurStateOnMain() < lott.GetDrawBlockNum() { if mainHeight-lott.GetLastTransToPurStateOnMain() < lott.GetDrawBlockNum() {
llog.Error("LotteryDraw", "action.height", action.height, "mainHeight", mainHeight, "GetLastTransToPurStateOnMain", lott.GetLastTransToPurState()) llog.Error("LotteryDraw", "action.height", action.height, "mainHeight", mainHeight, "GetLastTransToPurStateOnMain", lott.GetLastTransToPurState())
return nil, pty.ErrLotteryStatus return nil, pty.ErrLotteryStatus
...@@ -566,10 +532,8 @@ func (action *Action) LotteryClose(draw *pty.LotteryClose) (*types.Receipt, erro ...@@ -566,10 +532,8 @@ func (action *Action) LotteryClose(draw *pty.LotteryClose) (*types.Receipt, erro
} }
//random used for verification in solo //random used for verification in solo
func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 { func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) (int64, error) {
var num int64 var num int64
var msg types.Message
var hash []byte
if isSolo { if isSolo {
//used for internal verification //used for internal verification
num = 12345 num = 12345
...@@ -577,51 +541,23 @@ func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 { ...@@ -577,51 +541,23 @@ func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 {
//发消息给randnum模块 //发消息给randnum模块
//在主链上,当前高度查询不到,如果要保证区块个数,高度传入action.height-1 //在主链上,当前高度查询不到,如果要保证区块个数,高度传入action.height-1
llog.Debug("findLuckyNum on randnum module") llog.Debug("findLuckyNum on randnum module")
if !types.IsPara() { param := &types.ReqRandHash{
blockHash, err := action.api.GetBlockHash(&types.ReqInt{Height: action.height - 1}) ExecName: "ticket",
if err != nil { BlockNum: blockNum,
return -1 Hash: action.lottery.GetLastHash(),
} }
hash, err := action.lottery.GetExecutorAPI().GetRandNum(param)
req := &types.ReqRandHash{ExecName: "ticket", Hash: blockHash.Hash, BlockNum: blockNum} if err != nil {
msg, err = action.api.Query("ticket", "RandNumHash", req) return -1, err
if err != nil {
return -1
}
reply := msg.(*types.ReplyHash)
hash = reply.Hash
} else {
txs := action.lottery.GetTxs()
if len(txs) < action.index+1 {
llog.Error("findLuckyNum", "len(txs)", len(txs), "index", action.index)
return -1
}
msg, err := action.api.Query("paracross", "GetMainBlockHash", txs[0])
if err != nil {
return -1
}
queryReply := msg.(*types.ReplyHash)
mainBlockHash := queryReply.Hash
req := &types.ReqRandHash{ExecName: "ticket", Hash: mainBlockHash, BlockNum: blockNum}
reply, err := action.grpcClient.QueryRandNum(context.Background(), req)
if err != nil {
return -1
}
hash = reply.Hash
} }
baseNum, err := strconv.ParseUint(common.ToHex(hash[0:4]), 0, 64) baseNum, err := strconv.ParseUint(common.ToHex(hash[0:4]), 0, 64)
llog.Debug("findLuckyNum", "baseNum", baseNum) llog.Debug("findLuckyNum", "baseNum", baseNum)
if err != nil { if err != nil {
llog.Error("findLuckyNum", "err", err) return -1, err
return -1
} }
num = int64(baseNum) % luckyNumMol num = int64(baseNum) % luckyNumMol
} }
return num return num, nil
} }
func checkFundAmount(luckynum int64, guessnum int64, way int64) (int64, int64) { func checkFundAmount(luckynum int64, guessnum int64, way int64) (int64, int64) {
...@@ -639,9 +575,9 @@ func checkFundAmount(luckynum int64, guessnum int64, way int64) (int64, int64) { ...@@ -639,9 +575,9 @@ func checkFundAmount(luckynum int64, guessnum int64, way int64) (int64, int64) {
} }
func (action *Action) checkDraw(lott *LotteryDB) (*types.Receipt, *pty.LotteryUpdateBuyInfo, *pty.LotteryGainInfos, error) { func (action *Action) checkDraw(lott *LotteryDB) (*types.Receipt, *pty.LotteryUpdateBuyInfo, *pty.LotteryGainInfos, error) {
luckynum := action.findLuckyNum(false, lott) luckynum, err := action.findLuckyNum(false, lott)
if luckynum < 0 || luckynum >= luckyNumMol { if luckynum < 0 || luckynum >= luckyNumMol {
return nil, nil, nil, pty.ErrLotteryErrLuckyNum return nil, nil, nil, err
} }
llog.Debug("checkDraw", "luckynum", luckynum) llog.Debug("checkDraw", "luckynum", luckynum)
...@@ -755,14 +691,8 @@ func (action *Action) checkDraw(lott *LotteryDB) (*types.Receipt, *pty.LotteryUp ...@@ -755,14 +691,8 @@ func (action *Action) checkDraw(lott *LotteryDB) (*types.Receipt, *pty.LotteryUp
action.recordMissing(lott) action.recordMissing(lott)
if types.IsPara() { if types.IsPara() {
mainHeight := action.GetMainHeightByTxHash(action.txhash) lott.LastTransToDrawStateOnMain = action.lottery.GetMainHeight()
if mainHeight < 0 {
llog.Error("LotteryDraw", "mainHeight", mainHeight)
return nil, nil, nil, pty.ErrLotteryStatus
}
lott.LastTransToDrawStateOnMain = mainHeight
} }
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, &updateInfo, &gainInfos, nil return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, &updateInfo, &gainInfos, nil
} }
func (action *Action) recordMissing(lott *LotteryDB) { func (action *Action) recordMissing(lott *LotteryDB) {
......
...@@ -71,17 +71,6 @@ maxTxNumPerAccount=10000 ...@@ -71,17 +71,6 @@ maxTxNumPerAccount=10000
name="para" name="para"
genesisBlockTime=1514533394 genesisBlockTime=1514533394
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt" genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
ParaRemoteGrpcClient = "localhost:8802"
#主链指定高度的区块开始同步
startHeight=20
#打包时间间隔,单位秒
writeBlockSeconds=2
#主链每隔几个没有相关交易的区块,平行链上打包空区块
emptyBlockInterval=4
#验证账户,验证节点需要配置自己的账户,并且钱包导入对应种子,非验证节点留空
authAccount="1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
#等待平行链共识消息在主链上链并成功的块数,超出会重发共识消息,最小是2
waitBlocks4CommitMsg=2
[mver.consensus] [mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5" fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
...@@ -98,6 +87,19 @@ maxTxNumber = 1600 #160 ...@@ -98,6 +87,19 @@ maxTxNumber = 1600 #160
targetTimespan = 2304 targetTimespan = 2304
targetTimePerBlock = 16 targetTimePerBlock = 16
[consensus.sub.para]
ParaRemoteGrpcClient = "localhost:8802"
#主链指定高度的区块开始同步
startHeight=20
#打包时间间隔,单位秒
writeBlockSeconds=2
#主链每隔几个没有相关交易的区块,平行链上打包空区块
emptyBlockInterval=4
#验证账户,验证节点需要配置自己的账户,并且钱包导入对应种子,非验证节点留空
authAccount="1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
#等待平行链共识消息在主链上链并成功的块数,超出会重发共识消息,最小是2
waitBlocks4CommitMsg=2
[store] [store]
name="mavl" name="mavl"
driver="memdb" driver="memdb"
......
...@@ -72,19 +72,6 @@ maxTxNumPerAccount=10000 ...@@ -72,19 +72,6 @@ maxTxNumPerAccount=10000
name="para" name="para"
genesisBlockTime=1514533394 genesisBlockTime=1514533394
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt" genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
ParaRemoteGrpcClient="localhost:8802"
#主链指定高度的区块开始同步
startHeight=345850
#打包时间间隔,单位秒
writeBlockSeconds=2
#主链每隔几个没有相关交易的区块,平行链上打包空区块
emptyBlockInterval=50
#验证账户,验证节点需要配置自己的账户,并且钱包导入对应种子,非验证节点留空
authAccount=""
#等待平行链共识消息在主链上链并成功的块数,超出会重发共识消息,最小是2
waitBlocks4CommitMsg=2
searchHashMatchedBlockDepth=100
[mver.consensus] [mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5" fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
...@@ -101,6 +88,20 @@ maxTxNumber = 1600 #160 ...@@ -101,6 +88,20 @@ maxTxNumber = 1600 #160
targetTimespan = 2304 targetTimespan = 2304
targetTimePerBlock = 16 targetTimePerBlock = 16
[consensus.sub.para]
ParaRemoteGrpcClient="localhost:8802"
#主链指定高度的区块开始同步
startHeight=345850
#打包时间间隔,单位秒
writeBlockSeconds=2
#主链每隔几个没有相关交易的区块,平行链上打包空区块
emptyBlockInterval=50
#验证账户,验证节点需要配置自己的账户,并且钱包导入对应种子,非验证节点留空
authAccount=""
#等待平行链共识消息在主链上链并成功的块数,超出会重发共识消息,最小是2
waitBlocks4CommitMsg=2
searchHashMatchedBlockDepth=100
[store] [store]
name="mavl" name="mavl"
driver="leveldb" driver="leveldb"
......
...@@ -96,8 +96,7 @@ function para_transfer() { ...@@ -96,8 +96,7 @@ function para_transfer() {
txhash=$(para_configkey "${PARA_CLI}" "token-blacklist" "BTY") txhash=$(para_configkey "${PARA_CLI}" "token-blacklist" "BTY")
echo "txhash=$txhash" echo "txhash=$txhash"
block_wait "${PARA_CLI}" 1 query_tx "${PARA_CLI}" "${txhash}"
$PARA_CLI tx query -s "${txhash}"
} }
...@@ -114,14 +113,34 @@ function para_configkey() { ...@@ -114,14 +113,34 @@ function para_configkey() {
echo "${send}" echo "${send}"
} }
function query_tx() {
block_wait "${1}" 3
local times=100
while true; do
ret=$(${1} tx query -s "${2}" | jq -r ".tx.hash")
echo "query hash is ${2}, return ${ret} "
if [ "${ret}" != "${2}" ]; then
block_wait "${1}" 2
times=$((times - 1))
if [ $times -le 0 ]; then
echo "query tx=$2 failed"
exit 1
fi
else
echo "query tx=$2 success"
break
fi
done
}
function token_create() { function token_create() {
echo "=========== # para token test =============" echo "=========== # para token test ============="
echo "=========== # 1.token precreate =============" echo "=========== # 1.token precreate ============="
hash=$(${1} send token precreate -f 0.001 -i test -n guodunjifen -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -p 0 -s GD -t 10000 -k 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4) hash=$(${1} send token precreate -f 0.001 -i test -n guodunjifen -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -p 0 -s GD -t 10000 -k 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4)
echo "${hash}" echo "${hash}"
block_wait "${1}" 3 query_tx "${1}" "${hash}"
${1} tx query -s "${hash}"
${1} token get_precreated ${1} token get_precreated
owner=$(${1} token get_precreated | jq -r ".owner") owner=$(${1} token get_precreated | jq -r ".owner")
if [ "${owner}" != "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" ]; then if [ "${owner}" != "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" ]; then
...@@ -137,9 +156,8 @@ function token_create() { ...@@ -137,9 +156,8 @@ function token_create() {
echo "=========== # 2.token finish =============" echo "=========== # 2.token finish ============="
hash=$(${1} send token finish -f 0.001 -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -s GD -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc) hash=$(${1} send token finish -f 0.001 -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -s GD -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
echo "${hash}" echo "${hash}"
block_wait "${1}" 3 query_tx "${1}" "${hash}"
${1} tx query -s "${hash}"
${1} token get_finish_created ${1} token get_finish_created
owner=$(${1} token get_finish_created | jq -r ".owner") owner=$(${1} token get_finish_created | jq -r ".owner")
if [ "${owner}" != "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" ]; then if [ "${owner}" != "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" ]; then
...@@ -163,9 +181,8 @@ function token_transfer() { ...@@ -163,9 +181,8 @@ function token_transfer() {
echo "=========== # 2.token transfer =============" echo "=========== # 2.token transfer ============="
hash=$(${1} send token transfer -a 11 -s GD -t 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b) hash=$(${1} send token transfer -a 11 -s GD -t 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b)
echo "${hash}" echo "${hash}"
block_wait "${1}" 3 query_tx "${1}" "${hash}"
${1} tx query -s "${hash}"
${1} token token_balance -a 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -e token -s GD ${1} token token_balance -a 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -e token -s GD
balance=$(${1} token token_balance -a 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -e token -s GD | jq -r '.[]|.balance') balance=$(${1} token token_balance -a 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -e token -s GD | jq -r '.[]|.balance')
if [ "${balance}" != "11.0000" ]; then if [ "${balance}" != "11.0000" ]; then
...@@ -176,11 +193,10 @@ function token_transfer() { ...@@ -176,11 +193,10 @@ function token_transfer() {
echo "=========== # 3.token send exec =============" echo "=========== # 3.token send exec ============="
hash=$(${1} send token send_exec -a 11 -s GD -e paracross -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b) hash=$(${1} send token send_exec -a 11 -s GD -e paracross -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b)
echo "${hash}" echo "${hash}"
block_wait "${1}" 3 query_tx "${1}" "${hash}"
# $ ./build/chain33-cli exec addr -e user.p.para.paracross # $ ./build/chain33-cli exec addr -e user.p.para.paracross
# 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii # 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii
${1} tx query -s "${hash}"
${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD ${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD
balance=$(${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD | jq -r '.[]|.balance') balance=$(${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD | jq -r '.[]|.balance')
if [ "${balance}" != "11.0000" ]; then if [ "${balance}" != "11.0000" ]; then
...@@ -191,9 +207,8 @@ function token_transfer() { ...@@ -191,9 +207,8 @@ function token_transfer() {
echo "=========== # 4.token withdraw =============" echo "=========== # 4.token withdraw ============="
hash=$(${1} send token withdraw -a 11 -s GD -e paracross -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b) hash=$(${1} send token withdraw -a 11 -s GD -e paracross -k 0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b)
echo "${hash}" echo "${hash}"
block_wait "${1}" 3 query_tx "${1}" "${hash}"
${1} tx query -s "${hash}"
${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD ${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD
balance=$(${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD | jq -r '.[]|.balance') balance=$(${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD | jq -r '.[]|.balance')
if [ "${balance}" != "0.0000" ]; then if [ "${balance}" != "0.0000" ]; then
...@@ -213,10 +228,10 @@ function para_cross_transfer_withdraw() { ...@@ -213,10 +228,10 @@ function para_cross_transfer_withdraw() {
sleep 15 sleep 15
${CLI} send para asset_withdraw --title user.p.para. -a 0.7 -n test -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01 ${CLI} send para asset_withdraw --title user.p.para. -a 0.7 -n test -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k 4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01
times=100 local times=100
while true; do while true; do
acc=$(${CLI} account balance -e paracross -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv | jq -r ".balance") acc=$(${CLI} account balance -e paracross -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv | jq -r ".balance")
echo "account balance is ${acc}, except 9.3 " echo "account balance is ${acc}, expect 9.3 "
if [ "${acc}" != "9.3000" ]; then if [ "${acc}" != "9.3000" ]; then
block_wait "${CLI}" 2 block_wait "${CLI}" 2
times=$((times - 1)) times=$((times - 1))
......
...@@ -189,7 +189,7 @@ func CreateRawMinerTx(status *ParacrossNodeStatus) (*types.Transaction, error) { ...@@ -189,7 +189,7 @@ func CreateRawMinerTx(status *ParacrossNodeStatus) (*types.Transaction, error) {
// CreateRawTransferTx create paracross asset transfer tx with transfer and withdraw // CreateRawTransferTx create paracross asset transfer tx with transfer and withdraw
func (p ParacrossType) CreateRawTransferTx(action string, param json.RawMessage) (*types.Transaction, error) { func (p ParacrossType) CreateRawTransferTx(action string, param json.RawMessage) (*types.Transaction, error) {
tlog.Error("ParacrossType CreateTx failed", "action", action, "msg", string(param)) tlog.Info("ParacrossType CreateTx", "action", action, "msg", string(param))
tx, err := p.ExecTypeBase.CreateTx(action, param) tx, err := p.ExecTypeBase.CreateTx(action, param)
if err != nil { if err != nil {
tlog.Error("ParacrossType CreateTx failed", "err", err, "action", action, "msg", string(param)) tlog.Error("ParacrossType CreateTx failed", "err", err, "action", action, "msg", string(param))
......
...@@ -101,12 +101,7 @@ func (p ParacrossType) CreateTx(action string, message json.RawMessage) (*types. ...@@ -101,12 +101,7 @@ func (p ParacrossType) CreateTx(action string, message json.RawMessage) (*types.
} else if action == "ParacrossTransfer" || action == "Transfer" || } else if action == "ParacrossTransfer" || action == "Transfer" ||
action == "ParacrossWithdraw" || action == "Withdraw" || action == "ParacrossWithdraw" || action == "Withdraw" ||
action == "ParacrossTransferToExec" || action == "TransferToExec" { action == "ParacrossTransferToExec" || action == "TransferToExec" {
var param types.CreateTx
err := json.Unmarshal(message, &param)
if err != nil {
glog.Error("CreateTx", "Error", err)
return nil, types.ErrInvalidParam
}
return p.CreateRawTransferTx(action, message) return p.CreateRawTransferTx(action, message)
} }
......
...@@ -19,7 +19,7 @@ const ( ...@@ -19,7 +19,7 @@ const (
// GetRandNum for ticket executor // GetRandNum for ticket executor
func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Message, error) { func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Message, error) {
tlog.Debug("GetRandNum", "blockHash", blockHash, "blockNum", blockNum) tlog.Debug("GetRandNum", "blockHash", common.ToHex(blockHash), "blockNum", blockNum)
if blockNum < minBlockNum { if blockNum < minBlockNum {
blockNum = minBlockNum blockNum = minBlockNum
...@@ -35,6 +35,11 @@ func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Messag ...@@ -35,6 +35,11 @@ func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Messag
if err != nil { if err != nil {
return nil, err return nil, err
} }
//如果是genesis block 那么直接返回一个固定值,防止测试的时候出错
if txActions == nil && err == nil {
modify := common.Sha256([]byte("hello"))
return &types.ReplyHash{Hash: modify}, nil
}
var modifies []byte var modifies []byte
var bits uint32 var bits uint32
var ticketIds string var ticketIds string
...@@ -59,7 +64,7 @@ func (ticket *Ticket) getTxActions(blockHash []byte, blockNum int64) ([]*tickett ...@@ -59,7 +64,7 @@ func (ticket *Ticket) getTxActions(blockHash []byte, blockNum int64) ([]*tickett
var txActions []*tickettypes.TicketAction var txActions []*tickettypes.TicketAction
var reqHashes types.ReqHashes var reqHashes types.ReqHashes
currHash := blockHash currHash := blockHash
tlog.Debug("getTxActions", "blockHash", blockHash, "blockNum", blockNum) tlog.Debug("getTxActions", "blockHash", common.ToHex(blockHash), "blockNum", blockNum)
//根据blockHash,查询block,循环blockNum //根据blockHash,查询block,循环blockNum
for blockNum > 0 { for blockNum > 0 {
...@@ -69,22 +74,26 @@ func (ticket *Ticket) getTxActions(blockHash []byte, blockNum int64) ([]*tickett ...@@ -69,22 +74,26 @@ func (ticket *Ticket) getTxActions(blockHash []byte, blockNum int64) ([]*tickett
if err != nil { if err != nil {
return txActions, err return txActions, err
} }
if tempBlock.Head.Height <= 0 {
return nil, nil
}
reqHashes.Hashes = append(reqHashes.Hashes, currHash) reqHashes.Hashes = append(reqHashes.Hashes, currHash)
currHash = tempBlock.Head.ParentHash currHash = tempBlock.Head.ParentHash
if tempBlock.Head.Height < 0 && blockNum > 1 { if tempBlock.Head.Height < 0 && blockNum > 1 {
return txActions, types.ErrBlockNotFound return txActions, types.ErrBlockNotFound
} }
if tempBlock.Head.Height <= 1 {
break
}
blockNum-- blockNum--
} }
blockDetails, err := ticket.GetAPI().GetBlockByHashes(&reqHashes) blockDetails, err := ticket.GetAPI().GetBlockByHashes(&reqHashes)
if err != nil { if err != nil {
tlog.Error("getTxActions", "blockHash", blockHash, "blockNum", blockNum, "err", err) tlog.Error("getTxActions", "blockHash", blockHash, "blockNum", blockNum, "err", err)
return txActions, err return txActions, err
} }
for _, block := range blockDetails.Items { for _, block := range blockDetails.Items {
tlog.Debug("getTxActions", "blockHeight", block.Block.Height, "blockhash", block.Block.Hash()) tlog.Debug("getTxActions", "blockHeight", block.Block.Height, "blockhash", common.ToHex(block.Block.Hash()))
ticketAction, err := ticket.getMinerTx(block.Block) ticketAction, err := ticket.getMinerTx(block.Block)
if err != nil { if err != nil {
return txActions, err return txActions, err
...@@ -92,7 +101,6 @@ func (ticket *Ticket) getTxActions(blockHash []byte, blockNum int64) ([]*tickett ...@@ -92,7 +101,6 @@ func (ticket *Ticket) getTxActions(blockHash []byte, blockNum int64) ([]*tickett
txActions = append(txActions, ticketAction) txActions = append(txActions, ticketAction)
} }
return txActions, nil return txActions, nil
} }
func (ticket *Ticket) getMinerTx(current *types.Block) (*tickettypes.TicketAction, error) { func (ticket *Ticket) getMinerTx(current *types.Block) (*tickettypes.TicketAction, error) {
......
...@@ -43,7 +43,10 @@ func execBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er ...@@ -43,7 +43,10 @@ func execBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
block.TxHash = merkle.CalcMerkleRootCache(cacheTxs) block.TxHash = merkle.CalcMerkleRootCache(cacheTxs)
block.Txs = types.CacheToTxs(cacheTxs) block.Txs = types.CacheToTxs(cacheTxs)
//println("1") //println("1")
receipts := util.ExecTx(client, prevStateRoot, block) receipts, err := util.ExecTx(client, prevStateRoot, block)
if err != nil {
return nil, nil, err
}
var maplist = make(map[string]*types.KeyValue) var maplist = make(map[string]*types.KeyValue)
var kvset []*types.KeyValue var kvset []*types.KeyValue
var deltxlist = make(map[int]bool) var deltxlist = make(map[int]bool)
...@@ -94,7 +97,10 @@ func execBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er ...@@ -94,7 +97,10 @@ func execBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
var detail types.BlockDetail var detail types.BlockDetail
calcHash = util.ExecKVMemSet(client, prevStateRoot, block.Height, kvset, sync) calcHash, err = util.ExecKVMemSet(client, prevStateRoot, block.Height, kvset, sync)
if err != nil {
return nil, nil, err
}
//println("2") //println("2")
if errReturn && !bytes.Equal(block.StateHash, calcHash) { if errReturn && !bytes.Equal(block.StateHash, calcHash) {
util.ExecKVSetRollback(client, calcHash) util.ExecKVSetRollback(client, calcHash)
......
...@@ -230,7 +230,7 @@ func (chain *BlockChain) getLastHeader(msg queue.Message) { ...@@ -230,7 +230,7 @@ func (chain *BlockChain) getLastHeader(msg queue.Message) {
func (chain *BlockChain) addBlockDetail(msg queue.Message) { func (chain *BlockChain) addBlockDetail(msg queue.Message) {
blockDetail := msg.Data.(*types.BlockDetail) blockDetail := msg.Data.(*types.BlockDetail)
Height := blockDetail.Block.Height Height := blockDetail.Block.Height
chainlog.Info("EventAddBlockDetail", "height", blockDetail.Block.Height, "hash", common.HashHex(blockDetail.Block.Hash())) chainlog.Info("EventAddBlockDetail", "height", blockDetail.Block.Height, "parent", common.ToHex(blockDetail.Block.ParentHash))
//首先判断共识过来的block的parenthash是否是当前bestchain链的tip区块,如果不是就直接返回错误给共识模块 //首先判断共识过来的block的parenthash是否是当前bestchain链的tip区块,如果不是就直接返回错误给共识模块
blockDetail, err := chain.ProcAddBlockMsg(true, blockDetail, "self") blockDetail, err := chain.ProcAddBlockMsg(true, blockDetail, "self")
if err != nil { if err != nil {
......
#!/usr/bin/env bash
withdraw=$(../chain33-cli bty withdraw -e "ticket" -n "安全支出费用: $1" -a "$1")
send=$(../chain33-cli bty transfer -a "$1" -n "安全支出费用: $1" -t 1MY4pMgjpS2vWiaSDZasRhN47pcwEire32)
echo "cli wallet sign -d $withdraw -a 1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP >d:/a.txt"
echo "cli wallet sign -d $send -a 1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP >>d:/a.txt"
//这个包提供了平行链和主链的统一的访问接口
package api
import (
"context"
"errors"
"sync/atomic"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
/*
平行链可以访问的有两条链:
1. 通过 client.QueueProtocolAPI 事件访问 平行链本身
2. 通过 grpc 接口访问主链
通过 client.QueueProtocolAPI 和 grpc 都可能会产生 网络错误,或者超时的问题
这个时候,区块做异常处理的时候需要做一些特殊处理
接口函数:
1. GetBlockByHash
2. GetLastBlockHash
3. GetRandNum
*/
//ErrAPIEnv api的执行环境出问题,区块执行的时候,遇到这一个的错误需要retry
var ErrAPIEnv = errors.New("ErrAPIEnv")
//ExecutorAPI 提供给执行器使用的接口
//因为合约是主链和平行链通用的,所以,主链和平行链都可以调用这套接口
type ExecutorAPI interface {
GetBlockByHashes(param *types.ReqHashes) (*types.BlockDetails, error)
GetRandNum(param *types.ReqRandHash) ([]byte, error)
QueryTx(param *types.ReqHash) (*types.TransactionDetail, error)
IsErr() bool
}
type mainChainAPI struct {
api client.QueueProtocolAPI
errflag int32
}
//New 新建接口
func New(api client.QueueProtocolAPI, grpcaddr string) ExecutorAPI {
if types.IsPara() {
return newParaChainAPI(api, grpcaddr)
}
return &mainChainAPI{api: api}
}
func (api *mainChainAPI) QueryTx(param *types.ReqHash) (*types.TransactionDetail, error) {
data, err := api.api.QueryTx(param)
return data, seterr(err, &api.errflag)
}
func (api *mainChainAPI) IsErr() bool {
return atomic.LoadInt32(&api.errflag) == 1
}
func (api *mainChainAPI) GetRandNum(param *types.ReqRandHash) ([]byte, error) {
msg, err := api.api.Query(param.ExecName, "RandNumHash", param)
if err != nil {
return nil, seterr(err, &api.errflag)
}
reply, ok := msg.(*types.ReplyHash)
if !ok {
return nil, types.ErrTypeAsset
}
return reply.Hash, nil
}
func (api *mainChainAPI) GetBlockByHashes(param *types.ReqHashes) (*types.BlockDetails, error) {
data, err := api.api.GetBlockByHashes(param)
return data, seterr(err, &api.errflag)
}
type paraChainAPI struct {
api client.QueueProtocolAPI
grpcClient types.Chain33Client
errflag int32
}
func newParaChainAPI(api client.QueueProtocolAPI, grpcaddr string) ExecutorAPI {
paraRemoteGrpcClient := types.Conf("config.consensus.sub.para").GStr("ParaRemoteGrpcClient")
if grpcaddr != "" {
paraRemoteGrpcClient = grpcaddr
}
if paraRemoteGrpcClient == "" {
paraRemoteGrpcClient = "127.0.0.1:8002"
}
conn, err := grpc.Dial(paraRemoteGrpcClient, grpc.WithInsecure())
if err != nil {
panic(err)
}
grpcClient := types.NewChain33Client(conn)
return &paraChainAPI{api: api, grpcClient: grpcClient}
}
func (api *paraChainAPI) IsErr() bool {
return atomic.LoadInt32(&api.errflag) == 1
}
func (api *paraChainAPI) QueryTx(param *types.ReqHash) (*types.TransactionDetail, error) {
data, err := api.grpcClient.QueryTransaction(context.Background(), param)
return data, seterr(err, &api.errflag)
}
func (api *paraChainAPI) GetRandNum(param *types.ReqRandHash) ([]byte, error) {
reply, err := api.grpcClient.QueryRandNum(context.Background(), param)
if err != nil {
return nil, seterr(err, &api.errflag)
}
return reply.Hash, nil
}
func (api *paraChainAPI) GetBlockByHashes(param *types.ReqHashes) (*types.BlockDetails, error) {
data, err := api.grpcClient.GetBlockByHashes(context.Background(), param)
return data, seterr(err, &api.errflag)
}
func seterr(err error, flag *int32) error {
if IsGrpcError(err) || IsQueueError(err) {
atomic.StoreInt32(flag, 1)
}
return err
}
//IsGrpcError 判断系统api 错误,还是 rpc 本身的错误
func IsGrpcError(err error) bool {
if err == nil {
return false
}
if err == ErrAPIEnv {
return true
}
if grpc.Code(err) == codes.Unknown {
return false
}
return true
}
//IsQueueError 是否是队列错误
func IsQueueError(err error) bool {
if err == nil {
return false
}
if err == ErrAPIEnv {
return true
}
if err == queue.ErrQueueTimeout ||
err == queue.ErrQueueChannelFull ||
err == queue.ErrIsQueueClosed {
return true
}
return false
}
package api
import (
"errors"
"testing"
"time"
"github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/queue"
qmocks "github.com/33cn/chain33/queue/mocks"
"github.com/33cn/chain33/rpc"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
func TestAPI(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
eapi := New(api, "")
param := &types.ReqHashes{
Hashes: [][]byte{[]byte("hello")},
}
api.On("GetBlockByHashes", mock.Anything).Return(&types.BlockDetails{}, nil)
detail, err := eapi.GetBlockByHashes(param)
assert.Nil(t, err)
assert.Equal(t, detail, &types.BlockDetails{})
param2 := &types.ReqRandHash{
ExecName: "ticket",
BlockNum: 5,
Hash: []byte("hello"),
}
api.On("Query", "ticket", "RandNumHash", mock.Anything).Return(&types.ReplyHash{Hash: []byte("hello")}, nil)
randhash, err := eapi.GetRandNum(param2)
assert.Nil(t, err)
assert.Equal(t, randhash, []byte("hello"))
assert.Equal(t, false, eapi.IsErr())
api.On("QueryTx", mock.Anything).Return(&types.TransactionDetail{Height: 1}, nil)
param3 := &types.ReqHash{Hash: []byte("hash")}
txdetail, err := eapi.QueryTx(param3)
assert.Nil(t, err)
assert.Equal(t, int64(1), txdetail.Height)
types.SetTitleOnlyForTest("user.p.wzw.")
//testnode setup
rpcCfg := new(types.RPC)
rpcCfg.GrpcBindAddr = "127.0.0.1:8003"
rpcCfg.JrpcBindAddr = "127.0.0.1:8004"
rpcCfg.MainnetJrpcAddr = rpcCfg.JrpcBindAddr
rpcCfg.Whitelist = []string{"127.0.0.1", "0.0.0.0"}
rpcCfg.JrpcFuncWhitelist = []string{"*"}
rpcCfg.GrpcFuncWhitelist = []string{"*"}
rpc.InitCfg(rpcCfg)
server := rpc.NewGRpcServer(&qmocks.Client{}, api)
assert.NotNil(t, server)
go server.Listen()
time.Sleep(time.Second)
eapi = New(api, "")
_, err = eapi.GetBlockByHashes(param)
assert.Equal(t, true, IsGrpcError(err))
assert.Equal(t, false, IsGrpcError(nil))
assert.Equal(t, false, IsGrpcError(errors.New("xxxx")))
assert.Equal(t, true, eapi.IsErr())
eapi = New(api, "127.0.0.1:8003")
detail, err = eapi.GetBlockByHashes(param)
assert.Equal(t, err, nil)
assert.Equal(t, detail, &types.BlockDetails{})
randhash, err = eapi.GetRandNum(param2)
assert.Nil(t, err)
assert.Equal(t, randhash, []byte("hello"))
assert.Equal(t, false, eapi.IsErr())
param3 = &types.ReqHash{Hash: []byte("hash")}
txdetail, err = eapi.QueryTx(param3)
assert.Nil(t, err)
assert.Equal(t, int64(1), txdetail.Height)
//queue err
assert.Equal(t, false, IsQueueError(nil))
assert.Equal(t, false, IsQueueError(errors.New("xxxx")))
assert.Equal(t, true, IsQueueError(queue.ErrQueueTimeout))
assert.Equal(t, true, IsQueueError(queue.ErrIsQueueClosed))
assert.Equal(t, false, IsQueueError(errors.New("ErrIsQueueClosed")))
}
...@@ -78,7 +78,10 @@ func main() { ...@@ -78,7 +78,10 @@ func main() {
log.Info("execblock", "block height", *height) log.Info("execblock", "block height", *height)
prevState := blocks.Items[0].Block.StateHash prevState := blocks.Items[0].Block.StateHash
block := blocks.Items[1].Block block := blocks.Items[1].Block
receipt := util.ExecTx(q.Client(), prevState, block) receipt, err := util.ExecTx(q.Client(), prevState, block)
if err != nil {
panic(err)
}
for i, r := range receipt.GetReceipts() { for i, r := range receipt.GetReceipts() {
println("=======================") println("=======================")
println("tx index ", i) println("tx index ", i)
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/client" "github.com/33cn/chain33/client"
"github.com/33cn/chain33/client/api"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
drivers "github.com/33cn/chain33/system/dapp" drivers "github.com/33cn/chain33/system/dapp"
...@@ -21,29 +22,40 @@ type executor struct { ...@@ -21,29 +22,40 @@ type executor struct {
stateDB dbm.KV stateDB dbm.KV
localDB dbm.KVDB localDB dbm.KVDB
coinsAccount *account.DB coinsAccount *account.DB
ctx *executorCtx
height int64 height int64
blocktime int64 blocktime int64
// 增加区块的难度值,后面的执行器逻辑需要这些属性 // 增加区块的难度值,后面的执行器逻辑需要这些属性
difficulty uint64 difficulty uint64
txs []*types.Transaction txs []*types.Transaction
api client.QueueProtocolAPI api client.QueueProtocolAPI
execapi api.ExecutorAPI
receipts []*types.ReceiptData receipts []*types.ReceiptData
} }
func newExecutor(stateHash []byte, exec *Executor, height, blocktime int64, difficulty uint64, type executorCtx struct {
txs []*types.Transaction, receipts []*types.ReceiptData) *executor { stateHash []byte
height int64
blocktime int64
difficulty uint64
parentHash []byte
mainHash []byte
mainHeight int64
}
func newExecutor(ctx *executorCtx, exec *Executor, txs []*types.Transaction, receipts []*types.ReceiptData) *executor {
client := exec.client client := exec.client
enableMVCC := exec.pluginEnable["mvcc"] enableMVCC := exec.pluginEnable["mvcc"]
opt := &StateDBOption{EnableMVCC: enableMVCC, Height: height} opt := &StateDBOption{EnableMVCC: enableMVCC, Height: ctx.height}
localdb := NewLocalDB(client) localdb := NewLocalDB(client)
e := &executor{ e := &executor{
stateDB: NewStateDB(client, stateHash, localdb, opt), stateDB: NewStateDB(client, ctx.stateHash, localdb, opt),
localDB: localdb, localDB: localdb,
coinsAccount: account.NewCoinsAccount(), coinsAccount: account.NewCoinsAccount(),
height: height, height: ctx.height,
blocktime: blocktime, blocktime: ctx.blocktime,
difficulty: difficulty, difficulty: ctx.difficulty,
ctx: ctx,
txs: txs, txs: txs,
receipts: receipts, receipts: receipts,
} }
...@@ -136,7 +148,9 @@ func (e *executor) setEnv(exec drivers.Driver) { ...@@ -136,7 +148,9 @@ func (e *executor) setEnv(exec drivers.Driver) {
exec.SetStateDB(e.stateDB) exec.SetStateDB(e.stateDB)
exec.SetLocalDB(e.localDB) exec.SetLocalDB(e.localDB)
exec.SetEnv(e.height, e.blocktime, e.difficulty) exec.SetEnv(e.height, e.blocktime, e.difficulty)
exec.SetBlockInfo(e.ctx.parentHash, e.ctx.mainHash, e.ctx.mainHeight)
exec.SetAPI(e.api) exec.SetAPI(e.api)
e.execapi = exec.GetExecutorAPI()
exec.SetTxs(e.txs) exec.SetTxs(e.txs)
exec.SetReceipt(e.receipts) exec.SetReceipt(e.receipts)
} }
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"sync" "sync"
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/client/api"
clog "github.com/33cn/chain33/common/log" clog "github.com/33cn/chain33/common/log"
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/pluginmgr" "github.com/33cn/chain33/pluginmgr"
...@@ -156,7 +157,16 @@ func (exec *Executor) procExecQuery(msg queue.Message) { ...@@ -156,7 +157,16 @@ func (exec *Executor) procExecQuery(msg queue.Message) {
func (exec *Executor) procExecCheckTx(msg queue.Message) { func (exec *Executor) procExecCheckTx(msg queue.Message) {
datas := msg.GetData().(*types.ExecTxList) datas := msg.GetData().(*types.ExecTxList)
execute := newExecutor(datas.StateHash, exec, datas.Height, datas.BlockTime, datas.Difficulty, datas.Txs, nil) ctx := &executorCtx{
stateHash: datas.StateHash,
height: datas.Height,
blocktime: datas.BlockTime,
difficulty: datas.Difficulty,
mainHash: datas.MainHash,
mainHeight: datas.MainHeight,
parentHash: datas.ParentHash,
}
execute := newExecutor(ctx, exec, datas.Txs, nil)
execute.enableMVCC() execute.enableMVCC()
execute.api = exec.qclient execute.api = exec.qclient
//返回一个列表表示成功还是失败 //返回一个列表表示成功还是失败
...@@ -179,7 +189,16 @@ func (exec *Executor) procExecCheckTx(msg queue.Message) { ...@@ -179,7 +189,16 @@ func (exec *Executor) procExecCheckTx(msg queue.Message) {
func (exec *Executor) procExecTxList(msg queue.Message) { func (exec *Executor) procExecTxList(msg queue.Message) {
datas := msg.GetData().(*types.ExecTxList) datas := msg.GetData().(*types.ExecTxList)
execute := newExecutor(datas.StateHash, exec, datas.Height, datas.BlockTime, datas.Difficulty, datas.Txs, nil) ctx := &executorCtx{
stateHash: datas.StateHash,
height: datas.Height,
blocktime: datas.BlockTime,
difficulty: datas.Difficulty,
mainHash: datas.MainHash,
mainHeight: datas.MainHeight,
parentHash: datas.ParentHash,
}
execute := newExecutor(ctx, exec, datas.Txs, nil)
execute.enableMVCC() execute.enableMVCC()
execute.api = exec.qclient execute.api = exec.qclient
var receipts []*types.Receipt var receipts []*types.Receipt
...@@ -193,6 +212,10 @@ func (exec *Executor) procExecTxList(msg queue.Message) { ...@@ -193,6 +212,10 @@ func (exec *Executor) procExecTxList(msg queue.Message) {
} }
if tx.GroupCount == 0 { if tx.GroupCount == 0 {
receipt, err := execute.execTx(tx, index) receipt, err := execute.execTx(tx, index)
if api.IsGrpcError(err) || api.IsQueueError(err) {
msg.Reply(exec.client.NewMessage("", types.EventReceipts, err))
return
}
if err != nil { if err != nil {
receipts = append(receipts, types.NewErrReceipt(err)) receipts = append(receipts, types.NewErrReceipt(err))
continue continue
...@@ -217,6 +240,10 @@ func (exec *Executor) procExecTxList(msg queue.Message) { ...@@ -217,6 +240,10 @@ func (exec *Executor) procExecTxList(msg queue.Message) {
panic("len(receiptlist) must be equal tx.GroupCount") panic("len(receiptlist) must be equal tx.GroupCount")
} }
if err != nil { if err != nil {
if api.IsGrpcError(err) || api.IsQueueError(err) {
msg.Reply(exec.client.NewMessage("", types.EventReceipts, err))
return
}
for n := 0; n < int(tx.GroupCount); n++ { for n := 0; n < int(tx.GroupCount); n++ {
receipts = append(receipts, types.NewErrReceipt(err)) receipts = append(receipts, types.NewErrReceipt(err))
} }
...@@ -232,7 +259,16 @@ func (exec *Executor) procExecTxList(msg queue.Message) { ...@@ -232,7 +259,16 @@ func (exec *Executor) procExecTxList(msg queue.Message) {
func (exec *Executor) procExecAddBlock(msg queue.Message) { func (exec *Executor) procExecAddBlock(msg queue.Message) {
datas := msg.GetData().(*types.BlockDetail) datas := msg.GetData().(*types.BlockDetail)
b := datas.Block b := datas.Block
execute := newExecutor(b.StateHash, exec, b.Height, b.BlockTime, uint64(b.Difficulty), b.Txs, datas.Receipts) ctx := &executorCtx{
stateHash: b.StateHash,
height: b.Height,
blocktime: b.BlockTime,
difficulty: uint64(b.Difficulty),
mainHash: b.MainHash,
mainHeight: b.MainHeight,
parentHash: b.ParentHash,
}
execute := newExecutor(ctx, exec, b.Txs, datas.Receipts)
execute.enableMVCC() execute.enableMVCC()
execute.api = exec.qclient execute.api = exec.qclient
var kvset types.LocalDBSet var kvset types.LocalDBSet
...@@ -284,7 +320,16 @@ func (exec *Executor) procExecAddBlock(msg queue.Message) { ...@@ -284,7 +320,16 @@ func (exec *Executor) procExecAddBlock(msg queue.Message) {
func (exec *Executor) procExecDelBlock(msg queue.Message) { func (exec *Executor) procExecDelBlock(msg queue.Message) {
datas := msg.GetData().(*types.BlockDetail) datas := msg.GetData().(*types.BlockDetail)
b := datas.Block b := datas.Block
execute := newExecutor(b.StateHash, exec, b.Height, b.BlockTime, uint64(b.Difficulty), b.Txs, nil) ctx := &executorCtx{
stateHash: b.StateHash,
height: b.Height,
blocktime: b.BlockTime,
difficulty: uint64(b.Difficulty),
mainHash: b.MainHash,
mainHeight: b.MainHeight,
parentHash: b.ParentHash,
}
execute := newExecutor(ctx, exec, b.Txs, nil)
execute.enableMVCC() execute.enableMVCC()
execute.api = exec.qclient execute.api = exec.qclient
var kvset types.LocalDBSet var kvset types.LocalDBSet
......
...@@ -49,7 +49,15 @@ func TestExecutorGetTxGroup(t *testing.T) { ...@@ -49,7 +49,15 @@ func TestExecutorGetTxGroup(t *testing.T) {
txgroup.SignN(1, types.SECP256K1, priv2) txgroup.SignN(1, types.SECP256K1, priv2)
txgroup.SignN(2, types.SECP256K1, priv3) txgroup.SignN(2, types.SECP256K1, priv3)
txs = txgroup.GetTxs() txs = txgroup.GetTxs()
execute := newExecutor(nil, exec, 1, time.Now().Unix(), 1, txs, nil) ctx := &executorCtx{
stateHash: nil,
height: 1,
blocktime: time.Now().Unix(),
difficulty: 1,
mainHash: nil,
parentHash: nil,
}
execute := newExecutor(ctx, exec, txs, nil)
e := execute.loadDriver(txs[0], 0) e := execute.loadDriver(txs[0], 0)
execute.setEnv(e) execute.setEnv(e)
txs2 := e.GetTxs() txs2 := e.GetTxs()
...@@ -64,7 +72,7 @@ func TestExecutorGetTxGroup(t *testing.T) { ...@@ -64,7 +72,7 @@ func TestExecutorGetTxGroup(t *testing.T) {
//err tx group list //err tx group list
txs[0].Header = nil txs[0].Header = nil
execute = newExecutor(nil, exec, 1, time.Now().Unix(), 1, txs, nil) execute = newExecutor(ctx, exec, txs, nil)
e = execute.loadDriver(txs[0], 0) e = execute.loadDriver(txs[0], 0)
execute.setEnv(e) execute.setEnv(e)
_, err = e.GetTxGroup(len(txs) - 1) _, err = e.GetTxGroup(len(txs) - 1)
......
...@@ -76,7 +76,7 @@ func (client *client) Send(msg Message, waitReply bool) (err error) { ...@@ -76,7 +76,7 @@ func (client *client) Send(msg Message, waitReply bool) (err error) {
timeout = time.Minute timeout = time.Minute
} }
err = client.SendTimeout(msg, waitReply, timeout) err = client.SendTimeout(msg, waitReply, timeout)
if err == types.ErrTimeout { if err == ErrQueueTimeout {
panic(err) panic(err)
} }
return err return err
...@@ -85,7 +85,7 @@ func (client *client) Send(msg Message, waitReply bool) (err error) { ...@@ -85,7 +85,7 @@ func (client *client) Send(msg Message, waitReply bool) (err error) {
// SendTimeout 超时发送, msg 消息 ,waitReply 是否等待回应, timeout 超时时间 // SendTimeout 超时发送, msg 消息 ,waitReply 是否等待回应, timeout 超时时间
func (client *client) SendTimeout(msg Message, waitReply bool, timeout time.Duration) (err error) { func (client *client) SendTimeout(msg Message, waitReply bool, timeout time.Duration) (err error) {
if client.isClose() { if client.isClose() {
return types.ErrIsClosed return ErrIsQueueClosed
} }
if !waitReply { if !waitReply {
msg.chReply = nil msg.chReply = nil
...@@ -115,9 +115,9 @@ func (client *client) WaitTimeout(msg Message, timeout time.Duration) (Message, ...@@ -115,9 +115,9 @@ func (client *client) WaitTimeout(msg Message, timeout time.Duration) (Message,
case msg = <-msg.chReply: case msg = <-msg.chReply:
return msg, msg.Err() return msg, msg.Err()
case <-client.done: case <-client.done:
return Message{}, errors.New("client is closed") return Message{}, ErrIsQueueClosed
case <-t.C: case <-t.C:
return Message{}, types.ErrTimeout return Message{}, ErrQueueTimeout
} }
} }
...@@ -128,7 +128,7 @@ func (client *client) Wait(msg Message) (Message, error) { ...@@ -128,7 +128,7 @@ func (client *client) Wait(msg Message) (Message, error) {
timeout = 5 * time.Minute timeout = 5 * time.Minute
} }
msg, err := client.WaitTimeout(msg, timeout) msg, err := client.WaitTimeout(msg, timeout)
if err == types.ErrTimeout { if err == ErrQueueTimeout {
panic(err) panic(err)
} }
return msg, err return msg, err
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
package queue package queue
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"os/signal" "os/signal"
...@@ -32,6 +33,13 @@ const ( ...@@ -32,6 +33,13 @@ const (
defaultLowChanBuffer = 40960 defaultLowChanBuffer = 40960
) )
//消息队列的错误
var (
ErrIsQueueClosed = errors.New("ErrIsQueueClosed")
ErrQueueTimeout = errors.New("ErrQueueTimeout")
ErrQueueChannelFull = errors.New("ErrQueueChannelFull")
)
// DisableLog disable log // DisableLog disable log
func DisableLog() { func DisableLog() {
qlog.SetHandler(log.DiscardHandler()) qlog.SetHandler(log.DiscardHandler())
...@@ -162,7 +170,7 @@ func (q *queue) send(msg Message, timeout time.Duration) (err error) { ...@@ -162,7 +170,7 @@ func (q *queue) send(msg Message, timeout time.Duration) (err error) {
return nil return nil
default: default:
qlog.Debug("send chainfull", "msg", msg, "topic", msg.Topic, "sub", sub) qlog.Debug("send chainfull", "msg", msg, "topic", msg.Topic, "sub", sub)
return types.ErrChannelFull return ErrQueueChannelFull
} }
} }
t := time.NewTimer(timeout) t := time.NewTimer(timeout)
...@@ -171,7 +179,7 @@ func (q *queue) send(msg Message, timeout time.Duration) (err error) { ...@@ -171,7 +179,7 @@ func (q *queue) send(msg Message, timeout time.Duration) (err error) {
case sub.high <- msg: case sub.high <- msg:
case <-t.C: case <-t.C:
qlog.Debug("send timeout", "msg", msg, "topic", msg.Topic, "sub", sub) qlog.Debug("send timeout", "msg", msg, "topic", msg.Topic, "sub", sub)
return types.ErrTimeout return ErrQueueTimeout
} }
if msg.Topic != "store" { if msg.Topic != "store" {
qlog.Debug("send ok", "msg", msg, "topic", msg.Topic, "sub", sub) qlog.Debug("send ok", "msg", msg, "topic", msg.Topic, "sub", sub)
...@@ -192,8 +200,8 @@ func (q *queue) sendAsyn(msg Message) error { ...@@ -192,8 +200,8 @@ func (q *queue) sendAsyn(msg Message) error {
qlog.Debug("send asyn ok", "msg", msg) qlog.Debug("send asyn ok", "msg", msg)
return nil return nil
default: default:
qlog.Error("send asyn err", "msg", msg, "err", types.ErrChannelFull) qlog.Error("send asyn err", "msg", msg, "err", ErrQueueChannelFull)
return types.ErrChannelFull return ErrQueueChannelFull
} }
} }
...@@ -216,7 +224,7 @@ func (q *queue) sendLowTimeout(msg Message, timeout time.Duration) error { ...@@ -216,7 +224,7 @@ func (q *queue) sendLowTimeout(msg Message, timeout time.Duration) error {
return nil return nil
case <-t.C: case <-t.C:
qlog.Error("send asyn timeout", "msg", msg) qlog.Error("send asyn timeout", "msg", msg)
return types.ErrTimeout return ErrQueueTimeout
} }
} }
......
...@@ -43,14 +43,14 @@ func TestTimeout(t *testing.T) { ...@@ -43,14 +43,14 @@ func TestTimeout(t *testing.T) {
//再发送一个交易返回chain full //再发送一个交易返回chain full
err := client.SendTimeout(msg, true, 0) err := client.SendTimeout(msg, true, 0)
if err != types.ErrChannelFull { if err != ErrQueueChannelFull {
t.Error(err) t.Error(err)
return return
} }
//发送一个交易返回返回timeout //发送一个交易返回返回timeout
err = client.SendTimeout(msg, true, time.Millisecond) err = client.SendTimeout(msg, true, time.Millisecond)
if err != types.ErrTimeout { if err != ErrQueueTimeout {
t.Error(err) t.Error(err)
return return
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package commands package commands
import ( import (
"encoding/json"
"fmt" "fmt"
"math" "math"
"os" "os"
...@@ -133,15 +132,10 @@ func CreateAssetSendToExec(cmd *cobra.Command, args []string, fromExec string) { ...@@ -133,15 +132,10 @@ func CreateAssetSendToExec(cmd *cobra.Command, args []string, fromExec string) {
ExecName: exec, ExecName: exec,
} }
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpcTypes.CreateTxIn{ params := &rpcTypes.CreateTxIn{
Execer: types.ExecName(fromExec), Execer: types.ExecName(fromExec),
ActionName: "TransferToExec", ActionName: "TransferToExec",
Payload: data, Payload: types.MustPBToJSON(payload),
} }
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
...@@ -171,15 +165,10 @@ func CreateAssetWithdraw(cmd *cobra.Command, args []string, fromExec string) { ...@@ -171,15 +165,10 @@ func CreateAssetWithdraw(cmd *cobra.Command, args []string, fromExec string) {
Cointoken: symbol, Cointoken: symbol,
ExecName: exec, ExecName: exec,
} }
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpcTypes.CreateTxIn{ params := &rpcTypes.CreateTxIn{
Execer: types.ExecName(fromExec), Execer: types.ExecName(fromExec),
ActionName: "Withdraw", ActionName: "Withdraw",
Payload: data, Payload: types.MustPBToJSON(payload),
} }
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
...@@ -200,15 +189,10 @@ func CreateAssetTransfer(cmd *cobra.Command, args []string, fromExec string) { ...@@ -200,15 +189,10 @@ func CreateAssetTransfer(cmd *cobra.Command, args []string, fromExec string) {
Note: []byte(note), Note: []byte(note),
Cointoken: symbol, Cointoken: symbol,
} }
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpcTypes.CreateTxIn{ params := &rpcTypes.CreateTxIn{
Execer: types.ExecName(fromExec), Execer: types.ExecName(fromExec),
ActionName: "Transfer", ActionName: "Transfer",
Payload: data, Payload: types.MustPBToJSON(payload),
} }
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
......
...@@ -15,6 +15,7 @@ import ( ...@@ -15,6 +15,7 @@ import (
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/client" "github.com/33cn/chain33/client"
"github.com/33cn/chain33/client/api"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
...@@ -41,6 +42,7 @@ type Driver interface { ...@@ -41,6 +42,7 @@ type Driver interface {
GetDriverName() string GetDriverName() string
//执行器的别名(一个驱动(code),允许创建多个执行器,类似evm一份代码可以创建多个合约) //执行器的别名(一个驱动(code),允许创建多个执行器,类似evm一份代码可以创建多个合约)
GetName() string GetName() string
GetExecutorAPI() api.ExecutorAPI
//设置执行器的真实名称 //设置执行器的真实名称
SetName(string) SetName(string)
SetCurrentExecName(string) SetCurrentExecName(string)
...@@ -48,6 +50,7 @@ type Driver interface { ...@@ -48,6 +50,7 @@ type Driver interface {
IsFriend(myexec []byte, writekey []byte, othertx *types.Transaction) bool IsFriend(myexec []byte, writekey []byte, othertx *types.Transaction) bool
GetActionName(tx *types.Transaction) string GetActionName(tx *types.Transaction) string
SetEnv(height, blocktime int64, difficulty uint64) SetEnv(height, blocktime int64, difficulty uint64)
SetBlockInfo([]byte, []byte, int64)
CheckTx(tx *types.Transaction, index int) error CheckTx(tx *types.Transaction, index int) error
Exec(tx *types.Transaction, index int) (*types.Receipt, error) Exec(tx *types.Transaction, index int) (*types.Receipt, error)
ExecLocal(tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) ExecLocal(tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error)
...@@ -69,21 +72,24 @@ type Driver interface { ...@@ -69,21 +72,24 @@ type Driver interface {
// DriverBase defines driverbase type // DriverBase defines driverbase type
type DriverBase struct { type DriverBase struct {
statedb dbm.KV statedb dbm.KV
localdb dbm.KVDB localdb dbm.KVDB
coinsaccount *account.DB coinsaccount *account.DB
height int64 height int64
blocktime int64 blocktime int64
name string parentHash, mainHash []byte
curname string mainHeight int64
child Driver name string
childValue reflect.Value curname string
isFree bool child Driver
difficulty uint64 childValue reflect.Value
api client.QueueProtocolAPI isFree bool
txs []*types.Transaction difficulty uint64
receipts []*types.ReceiptData api client.QueueProtocolAPI
ety types.ExecutorType execapi api.ExecutorAPI
txs []*types.Transaction
receipts []*types.ReceiptData
ety types.ExecutorType
} }
// GetPayloadValue define get payload func // GetPayloadValue define get payload func
...@@ -99,6 +105,19 @@ func (d *DriverBase) GetExecutorType() types.ExecutorType { ...@@ -99,6 +105,19 @@ func (d *DriverBase) GetExecutorType() types.ExecutorType {
return d.ety return d.ety
} }
//GetLastHash 获取最后区块的hash,主链和平行链不同
func (d *DriverBase) GetLastHash() []byte {
if types.IsPara() {
return d.mainHash
}
return d.parentHash
}
//GetParentHash 获取上一个区块的hash
func (d *DriverBase) GetParentHash() []byte {
return d.parentHash
}
// GetFuncMap defines get execfuncmap func // GetFuncMap defines get execfuncmap func
func (d *DriverBase) GetFuncMap() map[string]reflect.Method { func (d *DriverBase) GetFuncMap() map[string]reflect.Method {
if d.ety == nil { if d.ety == nil {
...@@ -108,8 +127,9 @@ func (d *DriverBase) GetFuncMap() map[string]reflect.Method { ...@@ -108,8 +127,9 @@ func (d *DriverBase) GetFuncMap() map[string]reflect.Method {
} }
// SetAPI set queue protocol api // SetAPI set queue protocol api
func (d *DriverBase) SetAPI(api client.QueueProtocolAPI) { func (d *DriverBase) SetAPI(queueapi client.QueueProtocolAPI) {
d.api = api d.api = queueapi
d.execapi = api.New(queueapi, "")
} }
// GetAPI return queue protocol api // GetAPI return queue protocol api
...@@ -117,6 +137,11 @@ func (d *DriverBase) GetAPI() client.QueueProtocolAPI { ...@@ -117,6 +137,11 @@ func (d *DriverBase) GetAPI() client.QueueProtocolAPI {
return d.api return d.api
} }
// GetExecutorAPI return executor api
func (d *DriverBase) GetExecutorAPI() api.ExecutorAPI {
return d.execapi
}
// SetEnv set env // SetEnv set env
func (d *DriverBase) SetEnv(height, blocktime int64, difficulty uint64) { func (d *DriverBase) SetEnv(height, blocktime int64, difficulty uint64) {
d.height = height d.height = height
...@@ -124,6 +149,13 @@ func (d *DriverBase) SetEnv(height, blocktime int64, difficulty uint64) { ...@@ -124,6 +149,13 @@ func (d *DriverBase) SetEnv(height, blocktime int64, difficulty uint64) {
d.difficulty = difficulty d.difficulty = difficulty
} }
//SetBlockInfo 设置区块的信息
func (d *DriverBase) SetBlockInfo(parentHash, mainHash []byte, mainHeight int64) {
d.parentHash = parentHash
d.mainHash = mainHash
d.mainHeight = mainHeight
}
// SetIsFree set isfree // SetIsFree set isfree
func (d *DriverBase) SetIsFree(isFree bool) { func (d *DriverBase) SetIsFree(isFree bool) {
d.isFree = isFree d.isFree = isFree
...@@ -366,6 +398,14 @@ func (d *DriverBase) GetHeight() int64 { ...@@ -366,6 +398,14 @@ func (d *DriverBase) GetHeight() int64 {
return d.height return d.height
} }
// GetMainHeight return height
func (d *DriverBase) GetMainHeight() int64 {
if types.IsPara() {
return d.mainHeight
}
return d.height
}
// GetBlockTime return block time // GetBlockTime return block time
func (d *DriverBase) GetBlockTime() int64 { func (d *DriverBase) GetBlockTime() int64 {
return d.blocktime return d.blocktime
......
...@@ -2,8 +2,11 @@ package dapp ...@@ -2,8 +2,11 @@ package dapp
import ( import (
"testing" "testing"
"time"
"github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
...@@ -35,9 +38,12 @@ func (none *noneApp) GetDriverName() string { ...@@ -35,9 +38,12 @@ func (none *noneApp) GetDriverName() string {
return "none" return "none"
} }
func TestReigister(t *testing.T) { func init() {
Register("none", newnoneApp, 0) Register("none", newnoneApp, 0)
Register("demo", newdemoApp, 1) Register("demo", newdemoApp, 1)
}
func TestReigister(t *testing.T) {
_, err := LoadDriver("demo", 0) _, err := LoadDriver("demo", 0)
assert.Equal(t, err, types.ErrUnknowDriver) assert.Equal(t, err, types.ErrUnknowDriver)
_, err = LoadDriver("demo", 1) _, err = LoadDriver("demo", 1)
...@@ -65,6 +71,48 @@ func TestReigister(t *testing.T) { ...@@ -65,6 +71,48 @@ func TestReigister(t *testing.T) {
assert.Equal(t, "none", driver.GetDriverName()) assert.Equal(t, "none", driver.GetDriverName())
} }
func TestDriverAPI(t *testing.T) {
tx := &types.Transaction{Execer: []byte("demo")}
demo := LoadDriverAllow(tx, 0, 1).(*demoApp)
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
demo.SetEnv(1, time.Now().Unix(), 1)
demo.SetBlockInfo([]byte("parentHash"), []byte("mainHash"), 1)
demo.SetLocalDB(kvdb)
demo.SetStateDB(kvdb)
demo.SetAPI(&mocks.QueueProtocolAPI{})
assert.NotNil(t, demo.GetAPI())
assert.NotNil(t, demo.GetExecutorAPI())
types.SetTitleOnlyForTest("chain33")
assert.Equal(t, "parentHash", string(demo.GetParentHash()))
assert.Equal(t, "parentHash", string(demo.GetLastHash()))
types.SetTitleOnlyForTest("user.p.wzw.")
assert.Equal(t, "parentHash", string(demo.GetParentHash()))
assert.Equal(t, "mainHash", string(demo.GetLastHash()))
assert.Equal(t, int64(1), demo.GetMainHeight())
assert.Equal(t, true, IsDriverAddress(ExecAddress("none"), 0))
assert.Equal(t, false, IsDriverAddress(ExecAddress("demo"), 0))
assert.Equal(t, true, IsDriverAddress(ExecAddress("demo"), 1))
}
func TestExecAddress(t *testing.T) { func TestExecAddress(t *testing.T) {
assert.Equal(t, "16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp", ExecAddress("ticket")) assert.Equal(t, "16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp", ExecAddress("ticket"))
} }
func TestAllow(t *testing.T) {
tx := &types.Transaction{Execer: []byte("demo")}
demo := LoadDriverAllow(tx, 0, 1).(*demoApp)
assert.Equal(t, true, demo.AllowIsSame([]byte("demo")))
types.SetTitleOnlyForTest("user.p.wzw.")
assert.Equal(t, true, demo.AllowIsSame([]byte("user.p.wzw.demo")))
assert.Equal(t, false, demo.AllowIsSame([]byte("user.p.wzw2.demo")))
assert.Equal(t, false, demo.AllowIsUserDot1([]byte("user.p.wzw.demo")))
assert.Equal(t, true, demo.AllowIsUserDot1([]byte("user.demo")))
assert.Equal(t, true, demo.AllowIsUserDot1([]byte("user.p.wzw.user.demo")))
assert.Equal(t, true, demo.AllowIsUserDot2([]byte("user.p.wzw.user.demo.xxxx")))
assert.Equal(t, true, demo.AllowIsUserDot2([]byte("user.demo.xxxx")))
assert.Equal(t, nil, demo.Allow(tx, 0))
tx = &types.Transaction{Execer: []byte("demo2")}
assert.Equal(t, types.ErrNotAllow, demo.Allow(tx, 0))
assert.Equal(t, false, demo.IsFriend(nil, nil, nil))
}
...@@ -7,23 +7,12 @@ package dapp ...@@ -7,23 +7,12 @@ package dapp
//store package store the world - state data //store package store the world - state data
import ( import (
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
clog "github.com/33cn/chain33/common/log"
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
) )
var elog = log.New("module", "execs") var elog = log.New("module", "execs")
// SetLogLevel set log level
func SetLogLevel(level string) {
clog.SetLogLevel(level)
}
// DisableLog disable log
func DisableLog() {
elog.SetHandler(log.DiscardHandler())
}
// DriverCreate defines a drivercreate function // DriverCreate defines a drivercreate function
type DriverCreate func() Driver type DriverCreate func() Driver
......
...@@ -65,19 +65,12 @@ type Mempool struct { ...@@ -65,19 +65,12 @@ type Mempool struct {
// Consensus 配置 // Consensus 配置
type Consensus struct { type Consensus struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
GenesisBlockTime int64 `protobuf:"varint,2,opt,name=genesisBlockTime" json:"genesisBlockTime,omitempty"` GenesisBlockTime int64 `protobuf:"varint,2,opt,name=genesisBlockTime" json:"genesisBlockTime,omitempty"`
Minerstart bool `protobuf:"varint,3,opt,name=minerstart" json:"minerstart,omitempty"` Minerstart bool `protobuf:"varint,3,opt,name=minerstart" json:"minerstart,omitempty"`
Genesis string `protobuf:"bytes,4,opt,name=genesis" json:"genesis,omitempty"` Genesis string `protobuf:"bytes,4,opt,name=genesis" json:"genesis,omitempty"`
HotkeyAddr string `protobuf:"bytes,5,opt,name=hotkeyAddr" json:"hotkeyAddr,omitempty"` HotkeyAddr string `protobuf:"bytes,5,opt,name=hotkeyAddr" json:"hotkeyAddr,omitempty"`
ForceMining bool `protobuf:"varint,6,opt,name=forceMining" json:"forceMining,omitempty"` ForceMining bool `protobuf:"varint,6,opt,name=forceMining" json:"forceMining,omitempty"`
WriteBlockSeconds int64 `protobuf:"varint,20,opt,name=writeBlockSeconds" json:"writeBlockSeconds,omitempty"`
ParaRemoteGrpcClient string `protobuf:"bytes,22,opt,name=paraRemoteGrpcClient" json:"paraRemoteGrpcClient,omitempty"`
StartHeight int64 `protobuf:"varint,23,opt,name=startHeight" json:"startHeight,omitempty"`
EmptyBlockInterval int64 `protobuf:"varint,24,opt,name=emptyBlockInterval" json:"emptyBlockInterval,omitempty"`
AuthAccount string `protobuf:"bytes,25,opt,name=authAccount" json:"authAccount,omitempty"`
WaitBlocks4CommitMsg int32 `protobuf:"varint,26,opt,name=waitBlocks4CommitMsg" json:"waitBlocks4CommitMsg,omitempty"`
SearchHashMatchedBlockDepth int32 `protobuf:"varint,27,opt,name=searchHashMatchedBlockDepth" json:"searchHashMatchedBlockDepth,omitempty"`
} }
// Wallet 配置 // Wallet 配置
......
...@@ -217,8 +217,10 @@ func S(key string, value interface{}) { ...@@ -217,8 +217,10 @@ func S(key string, value interface{}) {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
if strings.HasPrefix(key, "config.") { if strings.HasPrefix(key, "config.") {
if isLocal() { if !isLocal() { //only local can modify for test
panic("prefix config. is readonly") panic("prefix config. is readonly")
} else {
tlog.Error("modify " + key + " is only for test")
} }
return return
} }
...@@ -559,6 +561,17 @@ func parseSubModule(cfg *subModule) (*ConfigSubModule, error) { ...@@ -559,6 +561,17 @@ func parseSubModule(cfg *subModule) (*ConfigSubModule, error) {
return &subcfg, nil return &subcfg, nil
} }
//ModifySubConfig json data modify
func ModifySubConfig(sub []byte, key string, value interface{}) ([]byte, error) {
var data map[string]interface{}
err := json.Unmarshal(sub, &data)
if err != nil {
return nil, err
}
data[key] = value
return json.Marshal(data)
}
func parseItem(data map[string]interface{}) map[string][]byte { func parseItem(data map[string]interface{}) map[string][]byte {
subconfig := make(map[string][]byte) subconfig := make(map[string][]byte)
if len(data) == 0 { if len(data) == 0 {
......
...@@ -27,7 +27,6 @@ var ( ...@@ -27,7 +27,6 @@ var (
ErrReRunGenesis = errors.New("ErrReRunGenesis") ErrReRunGenesis = errors.New("ErrReRunGenesis")
ErrActionNotSupport = errors.New("ErrActionNotSupport") ErrActionNotSupport = errors.New("ErrActionNotSupport")
ErrQueryNotSupport = errors.New("ErrQueryNotSupport") ErrQueryNotSupport = errors.New("ErrQueryNotSupport")
ErrChannelFull = errors.New("ErrChannelFull")
ErrAmount = errors.New("ErrAmount") ErrAmount = errors.New("ErrAmount")
ErrMinerIsStared = errors.New("ErrMinerIsStared") ErrMinerIsStared = errors.New("ErrMinerIsStared")
ErrMinerNotStared = errors.New("ErrMinerNotStared") ErrMinerNotStared = errors.New("ErrMinerNotStared")
...@@ -57,11 +56,11 @@ var ( ...@@ -57,11 +56,11 @@ var (
ErrToAddrNotSameToExecAddr = errors.New("ErrToAddrNotSameToExecAddr") ErrToAddrNotSameToExecAddr = errors.New("ErrToAddrNotSameToExecAddr")
ErrTypeAsset = errors.New("ErrTypeAsset") ErrTypeAsset = errors.New("ErrTypeAsset")
ErrEmpty = errors.New("ErrEmpty") ErrEmpty = errors.New("ErrEmpty")
ErrIsClosed = errors.New("ErrIsClosed")
ErrSendSameToRecv = errors.New("ErrSendSameToRecv") ErrSendSameToRecv = errors.New("ErrSendSameToRecv")
ErrExecNameNotAllow = errors.New("ErrExecNameNotAllow") ErrExecNameNotAllow = errors.New("ErrExecNameNotAllow")
ErrExecNotFound = errors.New("ErrExecNotFound") ErrExecNotFound = errors.New("ErrExecNotFound")
ErrLocalDBPerfix = errors.New("ErrLocalDBPerfix") ErrLocalDBPerfix = errors.New("ErrLocalDBPerfix")
ErrTimeout = errors.New("ErrTimeout")
ErrBlockHeaderDifficulty = errors.New("ErrBlockHeaderDifficulty") ErrBlockHeaderDifficulty = errors.New("ErrBlockHeaderDifficulty")
ErrNoTx = errors.New("ErrNoTx") ErrNoTx = errors.New("ErrNoTx")
ErrTxExist = errors.New("ErrTxExist") ErrTxExist = errors.New("ErrTxExist")
...@@ -99,7 +98,6 @@ var ( ...@@ -99,7 +98,6 @@ var (
ErrBlockHeightNoMatch = errors.New("ErrBlockHeightNoEqual") ErrBlockHeightNoMatch = errors.New("ErrBlockHeightNoEqual")
ErrParentTdNoExist = errors.New("ErrParentTdNoExist") ErrParentTdNoExist = errors.New("ErrParentTdNoExist")
ErrBlockHashNoMatch = errors.New("ErrBlockHashNoMatch") ErrBlockHashNoMatch = errors.New("ErrBlockHashNoMatch")
ErrIsClosed = errors.New("ErrIsClosed")
ErrDecode = errors.New("ErrDecode") ErrDecode = errors.New("ErrDecode")
ErrNotRollBack = errors.New("ErrNotRollBack") ErrNotRollBack = errors.New("ErrNotRollBack")
ErrPeerInfoIsNil = errors.New("ErrPeerInfoIsNil") ErrPeerInfoIsNil = errors.New("ErrPeerInfoIsNil")
......
...@@ -28,6 +28,7 @@ message Header { ...@@ -28,6 +28,7 @@ message Header {
Signature signature = 8; Signature signature = 8;
} }
// 参考Header解释 // 参考Header解释
// mainHash 平行链上使用的字段,代表这个区块的主链hash
message Block { message Block {
int64 version = 1; int64 version = 1;
bytes parentHash = 2; bytes parentHash = 2;
...@@ -36,6 +37,8 @@ message Block { ...@@ -36,6 +37,8 @@ message Block {
int64 height = 5; int64 height = 5;
int64 blockTime = 6; int64 blockTime = 6;
uint32 difficulty = 11; uint32 difficulty = 11;
bytes mainHash = 12;
int64 mainHeight = 13;
Signature signature = 8; Signature signature = 8;
repeated Transaction txs = 7; repeated Transaction txs = 7;
} }
......
...@@ -10,12 +10,15 @@ message Genesis { ...@@ -10,12 +10,15 @@ message Genesis {
} }
message ExecTxList { message ExecTxList {
bytes stateHash = 1; bytes stateHash = 1;
repeated Transaction txs = 2; bytes parentHash = 7;
int64 blockTime = 3; bytes mainHash = 8;
int64 height = 4; int64 mainHeight = 9;
uint64 difficulty = 5; int64 blockTime = 3;
bool isMempool = 6; int64 height = 4;
uint64 difficulty = 5;
bool isMempool = 6;
repeated Transaction txs = 2;
} }
message Query { message Query {
......
...@@ -30,9 +30,12 @@ func CheckBlock(client queue.Client, block *types.BlockDetail) error { ...@@ -30,9 +30,12 @@ func CheckBlock(client queue.Client, block *types.BlockDetail) error {
} }
//ExecTx : To send lists of txs within a block to exector for execution //ExecTx : To send lists of txs within a block to exector for execution
func ExecTx(client queue.Client, prevStateRoot []byte, block *types.Block) *types.Receipts { func ExecTx(client queue.Client, prevStateRoot []byte, block *types.Block) (*types.Receipts, error) {
list := &types.ExecTxList{ list := &types.ExecTxList{
StateHash: prevStateRoot, StateHash: prevStateRoot,
ParentHash: block.ParentHash,
MainHash: block.MainHash,
MainHeight: block.MainHeight,
Txs: block.Txs, Txs: block.Txs,
BlockTime: block.BlockTime, BlockTime: block.BlockTime,
Height: block.Height, Height: block.Height,
...@@ -43,14 +46,14 @@ func ExecTx(client queue.Client, prevStateRoot []byte, block *types.Block) *type ...@@ -43,14 +46,14 @@ func ExecTx(client queue.Client, prevStateRoot []byte, block *types.Block) *type
client.Send(msg, true) client.Send(msg, true)
resp, err := client.Wait(msg) resp, err := client.Wait(msg)
if err != nil { if err != nil {
panic(err) return nil, err
} }
receipts := resp.GetData().(*types.Receipts) receipts := resp.GetData().(*types.Receipts)
return receipts return receipts, nil
} }
//ExecKVMemSet : send kv values to memory store and set it in db //ExecKVMemSet : send kv values to memory store and set it in db
func ExecKVMemSet(client queue.Client, prevStateRoot []byte, height int64, kvset []*types.KeyValue, sync bool) []byte { func ExecKVMemSet(client queue.Client, prevStateRoot []byte, height int64, kvset []*types.KeyValue, sync bool) ([]byte, error) {
set := &types.StoreSet{StateHash: prevStateRoot, KV: kvset, Height: height} set := &types.StoreSet{StateHash: prevStateRoot, KV: kvset, Height: height}
setwithsync := &types.StoreSetWithSync{Storeset: set, Sync: sync} setwithsync := &types.StoreSetWithSync{Storeset: set, Sync: sync}
...@@ -58,10 +61,10 @@ func ExecKVMemSet(client queue.Client, prevStateRoot []byte, height int64, kvset ...@@ -58,10 +61,10 @@ func ExecKVMemSet(client queue.Client, prevStateRoot []byte, height int64, kvset
client.Send(msg, true) client.Send(msg, true)
resp, err := client.Wait(msg) resp, err := client.Wait(msg)
if err != nil { if err != nil {
panic(err) return nil, err
} }
hash := resp.GetData().(*types.ReplyHash) hash := resp.GetData().(*types.ReplyHash)
return hash.GetHash() return hash.GetHash(), nil
} }
//ExecKVSetCommit : commit the data set opetation to db //ExecKVSetCommit : commit the data set opetation to db
......
...@@ -9,7 +9,6 @@ Title="local" ...@@ -9,7 +9,6 @@ Title="local"
TestNet=true TestNet=true
FixTime=false FixTime=false
[log] [log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit # 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
loglevel = "debug" loglevel = "debug"
...@@ -102,6 +101,20 @@ targetTimePerBlock = 2 ...@@ -102,6 +101,20 @@ targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2] [mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff" powLimitBits = "0x1f2fffff"
[consensus.sub.para]
ParaRemoteGrpcClient="localhost:8802"
#主链指定高度的区块开始同步
startHeight=345850
#打包时间间隔,单位秒
writeBlockSeconds=2
#主链每隔几个没有相关交易的区块,平行链上打包空区块
emptyBlockInterval=50
#验证账户,验证节点需要配置自己的账户,并且钱包导入对应种子,非验证节点留空
authAccount=""
#等待平行链共识消息在主链上链并成功的块数,超出会重发共识消息,最小是2
waitBlocks4CommitMsg=2
searchHashMatchedBlockDepth=100
[consensus.sub.solo] [consensus.sub.solo]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt" genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394 genesisBlockTime=1514533394
...@@ -117,12 +130,12 @@ count=10000 ...@@ -117,12 +130,12 @@ count=10000
[[consensus.sub.ticket.genesis]] [[consensus.sub.ticket.genesis]]
minerAddr="1PUiGcbsccfxW3zuvHXZBJfznziph5miAo" minerAddr="1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"
returnAddr="1EbDHAXpoiewjPLX9uqoz38HsKqMXayZrF" returnAddr="1EbDHAXpoiewjPLX9uqoz38HsKqMXayZrF"
count=10000 count=1000
[[consensus.sub.ticket.genesis]] [[consensus.sub.ticket.genesis]]
minerAddr="1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX" minerAddr="1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX"
returnAddr="1KcCVZLSQYRUwE5EXTsAoQs9LuJW6xwfQa" returnAddr="1KcCVZLSQYRUwE5EXTsAoQs9LuJW6xwfQa"
count=10000 count=1000
[store] [store]
name="mavl" name="mavl"
......
...@@ -66,6 +66,7 @@ type Chain33Mock struct { ...@@ -66,6 +66,7 @@ type Chain33Mock struct {
store queue.Module store queue.Module
rpc *rpc.RPC rpc *rpc.RPC
cfg *types.Config cfg *types.Config
sub *types.ConfigSubModule
datadir string datadir string
lastsend []byte lastsend []byte
} }
...@@ -82,11 +83,15 @@ func NewWithConfig(cfg *types.Config, sub *types.ConfigSubModule, mockapi client ...@@ -82,11 +83,15 @@ func NewWithConfig(cfg *types.Config, sub *types.ConfigSubModule, mockapi client
func newWithConfig(cfg *types.Config, sub *types.ConfigSubModule, mockapi client.QueueProtocolAPI) *Chain33Mock { func newWithConfig(cfg *types.Config, sub *types.ConfigSubModule, mockapi client.QueueProtocolAPI) *Chain33Mock {
chain33globalLock.Lock() chain33globalLock.Lock()
return newWithConfigNoLock(cfg, sub, mockapi)
}
func newWithConfigNoLock(cfg *types.Config, sub *types.ConfigSubModule, mockapi client.QueueProtocolAPI) *Chain33Mock {
types.Init(cfg.Title, cfg) types.Init(cfg.Title, cfg)
q := queue.New("channel") q := queue.New("channel")
types.Debug = false types.Debug = false
datadir := util.ResetDatadir(cfg, "$TEMP/") datadir := util.ResetDatadir(cfg, "$TEMP/")
mock := &Chain33Mock{cfg: cfg, q: q, datadir: datadir} mock := &Chain33Mock{cfg: cfg, sub: sub, q: q, datadir: datadir}
mock.random = rand.New(rand.NewSource(types.Now().UnixNano())) mock.random = rand.New(rand.NewSource(types.Now().UnixNano()))
mock.exec = executor.New(cfg.Exec, sub.Exec) mock.exec = executor.New(cfg.Exec, sub.Exec)
...@@ -163,6 +168,14 @@ func (mock *Chain33Mock) Listen() { ...@@ -163,6 +168,14 @@ func (mock *Chain33Mock) Listen() {
l := len(mock.cfg.RPC.GrpcBindAddr) l := len(mock.cfg.RPC.GrpcBindAddr)
mock.cfg.RPC.GrpcBindAddr = mock.cfg.RPC.GrpcBindAddr[0:l-2] + ":" + fmt.Sprint(portgrpc) mock.cfg.RPC.GrpcBindAddr = mock.cfg.RPC.GrpcBindAddr[0:l-2] + ":" + fmt.Sprint(portgrpc)
} }
if mock.sub.Consensus["para"] != nil {
data, err := types.ModifySubConfig(mock.sub.Consensus["para"], "ParaRemoteGrpcClient", mock.cfg.RPC.GrpcBindAddr)
if err != nil {
panic(err)
}
mock.sub.Consensus["para"] = data
types.S("config.consensus.sub.para.ParaRemoteGrpcClient", mock.cfg.RPC.GrpcBindAddr)
}
} }
//GetBlockChain : //GetBlockChain :
...@@ -271,6 +284,11 @@ func (mock *Chain33Mock) GetCfg() *types.Config { ...@@ -271,6 +284,11 @@ func (mock *Chain33Mock) GetCfg() *types.Config {
//Close : //Close :
func (mock *Chain33Mock) Close() { func (mock *Chain33Mock) Close() {
mock.closeNoLock()
chain33globalLock.Unlock()
}
func (mock *Chain33Mock) closeNoLock() {
mock.chain.Close() mock.chain.Close()
mock.store.Close() mock.store.Close()
mock.mem.Close() mock.mem.Close()
...@@ -281,7 +299,6 @@ func (mock *Chain33Mock) Close() { ...@@ -281,7 +299,6 @@ func (mock *Chain33Mock) Close() {
mock.client.Close() mock.client.Close()
mock.rpc.Close() mock.rpc.Close()
os.RemoveAll(mock.datadir) os.RemoveAll(mock.datadir)
chain33globalLock.Unlock()
} }
//WaitHeight : //WaitHeight :
......
...@@ -130,7 +130,11 @@ func JSONPrint(t *testing.T, input interface{}) { ...@@ -130,7 +130,11 @@ func JSONPrint(t *testing.T, input interface{}) {
t.Error(err) t.Error(err)
return return
} }
t.Log(string(data)) if t == nil {
fmt.Println(string(data))
} else {
t.Log(string(data))
}
} }
// CreateManageTx : Create Manage Tx // CreateManageTx : Create Manage Tx
...@@ -245,7 +249,10 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er ...@@ -245,7 +249,10 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
block.TxHash = merkle.CalcMerkleRootCache(cacheTxs) block.TxHash = merkle.CalcMerkleRootCache(cacheTxs)
block.Txs = types.CacheToTxs(cacheTxs) block.Txs = types.CacheToTxs(cacheTxs)
receipts := ExecTx(client, prevStateRoot, block) receipts, err := ExecTx(client, prevStateRoot, block)
if err != nil {
return nil, nil, err
}
var kvset []*types.KeyValue var kvset []*types.KeyValue
var deltxlist = make(map[int]bool) var deltxlist = make(map[int]bool)
var rdata []*types.ReceiptData //save to db receipt log var rdata []*types.ReceiptData //save to db receipt log
...@@ -285,7 +292,10 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er ...@@ -285,7 +292,10 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
} }
var detail types.BlockDetail var detail types.BlockDetail
calcHash = ExecKVMemSet(client, prevStateRoot, block.Height, kvset, sync) calcHash, err = ExecKVMemSet(client, prevStateRoot, block.Height, kvset, sync)
if err != nil {
return nil, nil, err
}
if errReturn && !bytes.Equal(block.StateHash, calcHash) { if errReturn && !bytes.Equal(block.StateHash, calcHash) {
ExecKVSetRollback(client, calcHash) ExecKVSetRollback(client, calcHash)
if len(rdata) > 0 { if len(rdata) > 0 {
......
...@@ -139,7 +139,10 @@ func SaveAccountTomavl(client queue.Client, prevStateRoot []byte, accs []*types. ...@@ -139,7 +139,10 @@ func SaveAccountTomavl(client queue.Client, prevStateRoot []byte, accs []*types.
kvs := accountdb.GetKVSet(acc) kvs := accountdb.GetKVSet(acc)
kvset = append(kvset, kvs...) kvset = append(kvset, kvs...)
} }
hash := util.ExecKVMemSet(client, prevStateRoot, 0, kvset, true) hash, err := util.ExecKVMemSet(client, prevStateRoot, 0, kvset, true)
if err != nil {
panic(err)
}
Statehash = hash Statehash = hash
util.ExecKVSetCommit(client, Statehash) util.ExecKVSetCommit(client, Statehash)
return hash return hash
......
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