Commit 5e1089b0 authored by mdj33's avatar mdj33 Committed by 33cn

add getblockbySeq interface and ut

parent 0cb95366
......@@ -349,11 +349,11 @@ func (client *client) getLastBlockInfo() (int64, *types.Block, []byte, int64, er
if seq == -1 {
seq = 0
}
savedBlockOnMain, _, err := client.GetBlockOnMainBySeq(seq)
main, err := client.GetBlockOnMainBySeq(seq)
if err != nil {
return -2, nil, nil, -2, err
}
return blockedSeq, lastBlock, savedBlockOnMain.Block.Hash(), savedBlockOnMain.Block.Height, nil
return blockedSeq, lastBlock, main.Seq.Hash, main.Detail.Block.Height, nil
}
......@@ -404,72 +404,35 @@ func (client *client) GetSeqByHashOnMainChain(hash []byte) (int64, error) {
return seq.Data, nil
}
func (client *client) GetBlocksByHashesFromMainChain(hashes [][]byte) (*types.BlockDetails, error) {
req := &types.ReqHashes{Hashes: hashes}
blocks, err := client.grpcClient.GetBlockByHashes(context.Background(), req)
func (client *client) GetBlockOnMainBySeq(seq int64) (*types.BlockSeq, error) {
blockSeq, err := client.grpcClient.GetBlockBySeq(context.Background(), &types.Int64{Data: seq})
if err != nil {
plog.Error("GetBlocksByHashesFromMainChain", "Error", err.Error())
plog.Error("Not found block on main", "seq", seq)
return nil, err
}
return blocks, nil
}
func (client *client) GetBlockHashFromMainChain(start int64, end int64) (*types.BlockSequences, error) {
req := &types.ReqBlocks{Start: start, End: end, IsDetail: true, Pid: []string{}}
blockSeqs, err := client.grpcClient.GetBlockSequences(context.Background(), req)
if err != nil {
plog.Error("GetBlockHashFromMainChain", "Error", err.Error())
return nil, err
}
return blockSeqs, nil
}
func (client *client) GetBlockOnMainBySeq(seq int64) (*types.BlockDetail, int64, error) {
blockSeqs, err := client.GetBlockHashFromMainChain(seq, seq)
if err != nil {
plog.Error("Not found block hash on seq", "start", seq, "end", seq)
return nil, -1, err
}
var hashes [][]byte
for _, item := range blockSeqs.Items {
hashes = append(hashes, item.Hash)
}
blockDetails, err := client.GetBlocksByHashesFromMainChain(hashes)
if err != nil {
return nil, -1, err
}
//protect the boundary
if len(blockSeqs.Items) != len(blockDetails.Items) {
panic("Inconsistency between GetBlockSequences and GetBlockByHashes")
}
return blockDetails.Items[0], blockSeqs.Items[0].Type, nil
return blockSeq, nil
}
// preBlockHash to identify the same main node
func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*types.Transaction, *types.Block, int64, error) {
func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*types.Transaction, *types.BlockSeq, error) {
plog.Debug("Para consensus RequestTx")
lastSeq, err := client.GetLastSeqOnMainChain()
if err != nil {
return nil, nil, -1, err
return nil, nil, err
}
plog.Info("RequestTx", "LastMainSeq", lastSeq, "CurrSeq", currSeq)
if lastSeq >= currSeq {
blockDetail, seqTy, err := client.GetBlockOnMainBySeq(currSeq)
blockSeq, err := client.GetBlockOnMainBySeq(currSeq)
if err != nil {
return nil, nil, -1, err
return nil, nil, err
}
//genesis block start with seq=-1 not check
if currSeq == 0 ||
(bytes.Equal(preMainBlockHash, blockDetail.Block.ParentHash) && seqTy == addAct) ||
(bytes.Equal(preMainBlockHash, blockDetail.Block.Hash()) && seqTy == delAct) {
(bytes.Equal(preMainBlockHash, blockSeq.Detail.Block.ParentHash) && blockSeq.Seq.Type == addAct) ||
(bytes.Equal(preMainBlockHash, blockSeq.Seq.Hash) && blockSeq.Seq.Type == delAct) {
txs := client.FilterTxsForPara(blockDetail)
plog.Info("GetCurrentSeq", "Len of txs", len(txs), "seqTy", seqTy)
txs := client.FilterTxsForPara(blockSeq.Detail)
plog.Info("GetCurrentSeq", "Len of txs", len(txs), "seqTy", blockSeq.Seq.Type)
if lastSeq-currSeq > emptyBlockInterval {
client.isCaughtUp = false
......@@ -478,26 +441,26 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type
}
if client.authAccount != "" {
client.commitMsgClient.onMainBlockAdded(blockDetail)
client.commitMsgClient.onMainBlockAdded(blockSeq.Detail)
}
return txs, blockDetail.Block, seqTy, nil
return txs, blockSeq, nil
}
//not consistent case be processed at below
plog.Error("RequestTx", "preMainHash", common.Bytes2Hex(preMainBlockHash), "currSeq preMainHash", common.Bytes2Hex(blockDetail.Block.ParentHash),
"currSeq mainHash", common.Bytes2Hex(blockDetail.Block.Hash()), "curr seq", currSeq, "ty", seqTy, "currSeq Mainheight", blockDetail.Block.Height)
return nil, nil, -1, paracross.ErrParaCurHashNotMatch
plog.Error("RequestTx", "preMainHash", common.Bytes2Hex(preMainBlockHash), "currSeq preMainHash", common.Bytes2Hex(blockSeq.Detail.Block.ParentHash),
"currSeq mainHash", common.Bytes2Hex(blockSeq.Seq.Hash), "curr seq", currSeq, "ty", blockSeq.Seq.Type, "currSeq Mainheight", blockSeq.Detail.Block.Height)
return nil, nil, paracross.ErrParaCurHashNotMatch
}
//lastSeq < CurrSeq case:
//lastSeq = currSeq-1, main node not update
if lastSeq+1 == currSeq {
plog.Debug("Waiting new sequence from main chain")
return nil, nil, -1, paracross.ErrParaWaitingNewSeq
return nil, nil, paracross.ErrParaWaitingNewSeq
}
// 1. lastSeq < currSeq-1
// 2. lastSeq >= currSeq and seq not consistent or fork case
return nil, nil, -1, paracross.ErrParaCurHashNotMatch
return nil, nil, paracross.ErrParaCurHashNotMatch
}
//genesis block scenario, new main node's blockHash as preMainHash, genesis sequence+1 as currSeq
......@@ -620,7 +583,7 @@ func (client *client) CreateBlock() {
currSeq++
}
txs, blockOnMain, seqTy, err := client.RequestTx(currSeq, lastSeqMainHash)
txs, blockOnMain, err := client.RequestTx(currSeq, lastSeqMainHash)
if err != nil {
incSeqFlag = false
if err == paracross.ErrParaCurHashNotMatch {
......@@ -635,10 +598,10 @@ func (client *client) CreateBlock() {
continue
}
lastSeqMainHeight := blockOnMain.Height
lastSeqMainHash = blockOnMain.Hash()
if seqTy == delAct {
lastSeqMainHash = blockOnMain.ParentHash
lastSeqMainHeight := blockOnMain.Detail.Block.Height
lastSeqMainHash = blockOnMain.Seq.Hash
if blockOnMain.Seq.Type == delAct {
lastSeqMainHash = blockOnMain.Detail.Block.ParentHash
}
_, lastBlock, lastBlockMainHash, lastBlockMainHeight, err := client.getLastBlockInfo()
......@@ -650,9 +613,9 @@ func (client *client) CreateBlock() {
plog.Info("Parachain process block", "lastBlockSeq", lastSeq, "curSeq", currSeq,
"currSeqMainHeight", lastSeqMainHeight, "currSeqMainHash", common.ToHex(lastSeqMainHash),
"lastBlockMainHeight", lastBlockMainHeight, "lastBlockMainHash", common.ToHex(lastBlockMainHash), "seqTy", seqTy)
"lastBlockMainHeight", lastBlockMainHeight, "lastBlockMainHash", common.ToHex(lastBlockMainHash), "seqTy", blockOnMain.Seq.Type)
if seqTy == delAct {
if blockOnMain.Seq.Type == delAct {
if len(txs) == 0 {
if lastSeqMainHeight > lastBlockMainHeight {
incSeqFlag = true
......@@ -665,7 +628,7 @@ func (client *client) CreateBlock() {
if err != nil {
plog.Error(fmt.Sprintf("********************err:%v", err.Error()))
}
} else if seqTy == addAct {
} else if blockOnMain.Seq.Type == addAct {
if len(txs) == 0 {
if lastSeqMainHeight-lastBlockMainHeight < emptyBlockInterval {
incSeqFlag = true
......@@ -689,14 +652,14 @@ func (client *client) CreateBlock() {
}
// miner tx need all para node create, but not all node has auth account, here just not sign to keep align
func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main *types.Block) error {
func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main *types.BlockSeq) error {
status := &pt.ParacrossNodeStatus{
Title: types.GetTitle(),
Height: block.Height,
PreBlockHash: block.ParentHash,
PreStateHash: preStateHash,
MainBlockHash: main.Hash(),
MainBlockHeight: main.Height,
MainBlockHash: main.Seq.Hash,
MainBlockHeight: main.Detail.Block.Height,
}
tx, err := paracross.CreateRawMinerTx(status)
......@@ -710,7 +673,7 @@ func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main *
}
func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transaction, seq int64, mainBlock *types.Block) error {
func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transaction, seq int64, mainBlock *types.BlockSeq) error {
var newblock types.Block
plog.Debug(fmt.Sprintf("the len txs is: %v", len(txs)))
newblock.ParentHash = lastBlock.Hash()
......@@ -719,7 +682,7 @@ func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transacti
//挖矿固定难度
newblock.Difficulty = types.GetP(0).PowLimitBits
newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs)
newblock.BlockTime = mainBlock.BlockTime
newblock.BlockTime = mainBlock.Detail.Block.BlockTime
err := client.addMinerTx(lastBlock.StateHash, &newblock, mainBlock)
if err != nil {
......
......@@ -36,7 +36,7 @@ func init() {
pp.Init("paracross", nil)
random = rand.New(rand.NewSource(types.Now().UnixNano()))
consensusInterval = 2
log.SetLogLevel("debug")
log.SetLogLevel("error")
}
type suiteParaCommitMsg struct {
......@@ -72,17 +72,16 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu
s.store.SetQueueClient(q.Client())
s.para = New(cfg.Consensus, sub.Consensus["para"]).(*client)
s.grpcCli = &typesmocks.Chain33Client{}
blockHash := &types.BlockSequence{
Hash: []byte("1"),
Type: 1,
}
blockSeqs := &types.BlockSequences{Items: []*types.BlockSequence{blockHash}}
s.grpcCli.On("GetBlockSequences", mock.Anything, mock.Anything).Return(blockSeqs, errors.New("nil"))
block := &types.Block{}
blockDetail := &types.BlockDetail{Block: block}
blockDetails := &types.BlockDetails{Items: []*types.BlockDetail{blockDetail}}
s.grpcCli.On("GetBlockByHashes", mock.Anything, mock.Anything).Return(blockDetails, errors.New("nil"))
blockSeq := &types.BlockSeq{
Seq: &types.BlockSequence{
Hash: []byte("1"),
Type: 1,
},
Detail: &types.BlockDetail{Block: block},
}
s.grpcCli.On("GetBlockBySeq", mock.Anything, mock.Anything).Return(blockSeq, errors.New("nil"))
//data := &types.Int64{1}
s.grpcCli.On("GetLastBlockSequence", mock.Anything, mock.Anything).Return(nil, errors.New("nil"))
reply := &types.Reply{IsOk: true}
......@@ -145,11 +144,59 @@ func (s *suiteParaCommitMsg) TestRun_1() {
plog.Error("para test--2", "err", err.Error())
}
plog.Info("para test---------", "last height", lastBlock.Height)
s.Equal(int64(1), lastBlock.Height)
s.para.createBlock(lastBlock, nil, 1, getMainBlock(2, lastBlock.BlockTime+1))
time.Sleep(time.Second * 3)
time.Sleep(time.Second * 1)
lastBlock, err = s.para.RequestLastBlock()
if err != nil {
plog.Error("para test--2", "err", err.Error())
}
plog.Info("para test---------", "last height", lastBlock.Height)
s.Equal(int64(2), lastBlock.Height)
s.para.createBlock(lastBlock, nil, 2, getMainBlock(3, lastBlock.BlockTime+1))
time.Sleep(time.Second * 1)
lastBlock, err = s.para.RequestLastBlock()
if err != nil {
plog.Error("para test--3", "err", err.Error())
}
s.Equal(int64(3), lastBlock.Height)
s.testRunGetMinerTxInfo()
s.testRunRmvBlock()
time.Sleep(time.Second * 1)
lastBlock, err = s.para.RequestLastBlock()
s.para.DelBlock(lastBlock, 2)
time.Sleep(time.Second * 3)
if lastBlock.Height > 0 {
s.para.DelBlock(lastBlock, 2)
time.Sleep(time.Second * 1)
}
}
func (s *suiteParaCommitMsg) testRunGetMinerTxInfo() {
lastBlock, err := s.para.RequestLastBlock()
s.Nil(err)
plog.Info("para test testRunGetMinerTxInfo--------------", "last height", lastBlock.Height)
s.True(lastBlock.Height > 1)
status, err := getMinerTxInfo(lastBlock)
s.Nil(err)
s.Equal(int64(3), status.MainBlockHeight)
}
func (s *suiteParaCommitMsg) testRunRmvBlock() {
lastBlock, err := s.para.RequestLastBlock()
s.Nil(err)
plog.Info("para test testRunRmvBlock------------pre", "last height", lastBlock.Height)
s.True(lastBlock.Height > 1)
s.para.removeBlocks(1)
lastBlock, err = s.para.RequestLastBlock()
s.Nil(err)
plog.Info("para test testRunRmvBlock----------after", "last height", lastBlock.Height)
s.Equal(int64(1), lastBlock.Height)
}
func TestRunSuiteParaCommitMsg(t *testing.T) {
......@@ -158,7 +205,7 @@ func TestRunSuiteParaCommitMsg(t *testing.T) {
}
func (s *suiteParaCommitMsg) TearDownSuite() {
time.Sleep(time.Second * 5)
//time.Sleep(time.Second * 1)
s.block.Close()
s.para.Close()
s.exec.Close()
......@@ -169,9 +216,17 @@ func (s *suiteParaCommitMsg) TearDownSuite() {
}
func getMainBlock(height int64, BlockTime int64) *types.Block {
return &types.Block{
Height: height,
BlockTime: BlockTime,
func getMainBlock(height int64, BlockTime int64) *types.BlockSeq {
return &types.BlockSeq{
Num: height,
Seq: &types.BlockSequence{Hash: []byte(string(height)), Type: addAct},
Detail: &types.BlockDetail{
Block: &types.Block{
ParentHash: []byte(string(height - 1)),
Height: height,
BlockTime: BlockTime,
},
},
}
}
......@@ -6,7 +6,7 @@ package para
import (
"testing"
"errors"
"github.com/33cn/chain33/blockchain"
"github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/executor"
......@@ -15,9 +15,6 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
//"github.com/33cn/plugin/plugin/dapp/paracross/rpc"
"time"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/store"
_ "github.com/33cn/chain33/system"
......@@ -28,7 +25,7 @@ import (
func init() {
//types.Init("user.p.para.", nil)
log.SetLogLevel("debug")
log.SetLogLevel("error")
}
type suiteParaClient struct {
......@@ -44,6 +41,8 @@ type suiteParaClient struct {
network *p2p.P2p
}
func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule) {
q := queue.New("channel")
s.q = q
......@@ -59,42 +58,15 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule)
s.store.SetQueueClient(q.Client())
//cfg.Consensus.StartHeight = 0
cfg.Consensus.EmptyBlockInterval = 1
//add block by UT below
cfg.Consensus.EmptyBlockInterval = 100
s.para = New(cfg.Consensus, sub.Consensus["para"]).(*client)
s.grpcCli = &typesmocks.Chain33Client{}
blockHash := &types.BlockSequence{
Hash: []byte("1"),
Type: 1,
}
blockSeqs := &types.BlockSequences{Items: []*types.BlockSequence{blockHash}}
s.grpcCli.On("GetBlockSequences", mock.Anything, mock.Anything).Return(blockSeqs, nil)
block := &types.Block{Height: 0}
blockDetail := &types.BlockDetail{Block: block}
blockDetails := &types.BlockDetails{Items: []*types.BlockDetail{blockDetail}}
s.grpcCli.On("GetBlockByHashes", mock.Anything, mock.Anything).Return(blockDetails, nil).Once()
block = &types.Block{Height: 6, BlockTime: 8888888888}
blockDetail = &types.BlockDetail{Block: block}
blockDetails = &types.BlockDetails{Items: []*types.BlockDetail{blockDetail}}
s.grpcCli.On("GetBlockByHashes", mock.Anything, mock.Anything).Return(blockDetails, nil).Once()
block = &types.Block{Height: 0}
blockDetail = &types.BlockDetail{Block: block}
blockDetails = &types.BlockDetails{Items: []*types.BlockDetail{blockDetail}}
s.grpcCli.On("GetBlockByHashes", mock.Anything, mock.Anything).Return(blockDetails, nil).Once()
block = &types.Block{Height: 0}
blockDetail = &types.BlockDetail{Block: block}
blockDetails = &types.BlockDetails{Items: []*types.BlockDetail{blockDetail}}
s.grpcCli.On("GetBlockByHashes", mock.Anything, mock.Anything).Return(blockDetails, nil)
seq := &types.Int64{Data: 1}
s.grpcCli.On("GetLastBlockSequence", mock.Anything, mock.Anything).Return(seq, nil).Once()
seq = &types.Int64{Data: 2}
s.grpcCli.On("GetLastBlockSequence", mock.Anything, mock.Anything).Return(seq, nil).Once()
seq = &types.Int64{Data: 3}
s.grpcCli.On("GetLastBlockSequence", mock.Anything, mock.Anything).Return(seq, nil)
seq = &types.Int64{Data: 1}
s.grpcCli.On("GetSequenceByHash", mock.Anything, mock.Anything).Return(seq, nil)
s.createBlockMock()
reply := &types.Reply{IsOk: true}
s.grpcCli.On("IsSync", mock.Anything, mock.Anything).Return(reply, nil)
......@@ -115,52 +87,74 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule)
s.network = p2p.New(cfg.P2P)
s.network.SetQueueClient(q.Client())
//create block self
s.createBlock()
}
func (s *suiteParaClient) TestRun_Test() {
//s.testGetBlock()
lastBlock, err := s.para.RequestLastBlock()
if err != nil {
plog.Error("para test", "err", err.Error())
func (s *suiteParaClient) createBlockMock() {
var i, hashdata int64
for i=0; i<3;i++{
hashdata = i
if i>0{
hashdata = i-1
}
block := &types.Block{
Height: i,
ParentHash: []byte(string(hashdata)),
}
blockSeq := &types.BlockSeq{
Seq: &types.BlockSequence{
Hash: []byte(string(i)),
Type: 1,
},
Detail: &types.BlockDetail{Block: block},
}
s.grpcCli.On("GetBlockBySeq", mock.Anything, &types.Int64{Data: i}).Return(blockSeq, nil)
}
plog.Info("para test---------1", "last height", lastBlock.Height)
s.para.createBlock(lastBlock, nil, 0, getMainBlock(2, lastBlock.BlockTime+1))
lastBlock, err = s.para.RequestLastBlock()
if err != nil {
plog.Error("para test--2", "err", err.Error())
}
plog.Info("para test---------", "last height", lastBlock.Height)
s.para.createBlock(lastBlock, nil, 1, getMainBlock(3, lastBlock.BlockTime+1))
time.Sleep(time.Second * 1)
s.testRunGetMinerTxInfo()
s.testRunRmvBlock()
// set block 3's parentHasn not equal, enter switch
block3 := &types.Block{
Height: 3,
ParentHash: []byte(string(1)),
}
blockSeq3 := &types.BlockSeq{
Seq: &types.BlockSequence{
Hash: []byte(string(3)),
Type: 1,
},
Detail: &types.BlockDetail{Block: block3},
}
s.grpcCli.On("GetBlockBySeq", mock.Anything, &types.Int64{Data: 3}).Return(blockSeq3, nil)
}
// RequestTx GetLastSeqOnMainChain
seq := &types.Int64{Data: 1}
s.grpcCli.On("GetLastBlockSequence", mock.Anything, mock.Anything).Return(seq, nil).Once()
seq = &types.Int64{Data: 2}
s.grpcCli.On("GetLastBlockSequence", mock.Anything, mock.Anything).Return(seq, nil).Once()
seq = &types.Int64{Data: 3}
s.grpcCli.On("GetLastBlockSequence", mock.Anything, mock.Anything).Return(seq, nil)
func (s *suiteParaClient) testRunGetMinerTxInfo() {
lastBlock, err := s.para.RequestLastBlock()
s.Nil(err)
plog.Info("para test testRunGetMinerTxInfo", "last height", lastBlock.Height)
s.True(lastBlock.Height > 1)
status, err := getMinerTxInfo(lastBlock)
s.Nil(err)
s.Equal(int64(3), status.MainBlockHeight)
// mock for switchHashMatchedBlock
s.grpcCli.On("GetSequenceByHash", mock.Anything, &types.ReqHash{Hash: []byte(string(3))}).Return(nil, errors.New("hash err")).Once()
s.grpcCli.On("GetSequenceByHash", mock.Anything, &types.ReqHash{Hash: []byte(string(2))}).Return(nil, errors.New("hash err")).Once()
// mock for removeBlocks
seq = &types.Int64{Data: 1}
s.grpcCli.On("GetSequenceByHash", mock.Anything, mock.Anything).Return(seq, nil)
}
func (s *suiteParaClient) testRunRmvBlock() {
lastBlock, err := s.para.RequestLastBlock()
s.Nil(err)
plog.Info("para test testRunGetMinerTxInfo", "last height", lastBlock.Height)
s.True(lastBlock.Height > 1)
s.para.removeBlocks(1)
lastBlock, err = s.para.RequestLastBlock()
s.Nil(err)
plog.Info("para test testRunGetMinerTxInfo", "last height", lastBlock.Height)
s.Equal(int64(1), lastBlock.Height)
func (s *suiteParaClient) createBlock() {
var i int64
for i = 0; i < 3; i++ {
lastBlock, err := s.para.RequestLastBlock()
if err != nil {
plog.Error("para test", "err", err.Error())
}
plog.Info("para test---------1", "last height", lastBlock.Height)
s.para.createBlock(lastBlock, nil, i, getMainBlock(i+1, lastBlock.BlockTime+1))
}
}
func (s *suiteParaClient) SetupSuite() {
......@@ -173,7 +167,7 @@ func TestRunSuiteParaClient(t *testing.T) {
}
func (s *suiteParaClient) TearDownSuite() {
time.Sleep(time.Second * 5)
//time.Sleep(time.Second * 2)
s.block.Close()
s.para.Close()
s.network.Close()
......
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