OSDN Git Service

netsync add test case (#365)
authoryahtoo <yahtoo.ma@gmail.com>
Tue, 30 Jul 2019 02:58:00 +0000 (10:58 +0800)
committerPaladz <yzhu101@uottawa.ca>
Tue, 30 Jul 2019 02:58:00 +0000 (10:58 +0800)
netsync/chainmgr/block_keeper.go
netsync/chainmgr/block_keeper_test.go
netsync/chainmgr/block_process_test.go
netsync/chainmgr/tool_test.go
netsync/peers/peer.go
test/mock/chain.go

index b810a1a..80c1277 100644 (file)
@@ -112,7 +112,7 @@ func (bk *blockKeeper) locateHeaders(locator []*bc.Hash, stopHash *bc.Hash, skip
        headers := make([]*types.BlockHeader, 0)
        stopHeader, err := bk.chain.GetHeaderByHash(stopHash)
        if err != nil {
        headers := make([]*types.BlockHeader, 0)
        stopHeader, err := bk.chain.GetHeaderByHash(stopHash)
        if err != nil {
-               return headers, nil
+               return headers, err
        }
 
        if !bk.chain.InMainChain(*stopHash) || stopHeader.Height < startHeader.Height {
        }
 
        if !bk.chain.InMainChain(*stopHash) || stopHeader.Height < startHeader.Height {
@@ -191,16 +191,13 @@ func (bk *blockKeeper) start() {
 }
 
 func (bk *blockKeeper) checkSyncType() int {
 }
 
 func (bk *blockKeeper) checkSyncType() int {
-       peer := bk.peers.BestIrreversiblePeer(consensus.SFFullNode | consensus.SFFastSync)
-       if peer == nil {
-               log.WithFields(log.Fields{"module": logModule}).Debug("can't find fast sync peer")
-               return noNeedSync
-       }
-
        bestHeight := bk.chain.BestBlockHeight()
        bestHeight := bk.chain.BestBlockHeight()
-       if peerIrreversibleHeight := peer.IrreversibleHeight(); peerIrreversibleHeight >= bestHeight+minGapStartFastSync {
-               bk.fastSync.setSyncPeer(peer)
-               return fastSyncType
+       peer := bk.peers.BestIrreversiblePeer(consensus.SFFullNode | consensus.SFFastSync)
+       if peer != nil {
+               if peerIrreversibleHeight := peer.IrreversibleHeight(); peerIrreversibleHeight >= bestHeight+minGapStartFastSync {
+                       bk.fastSync.setSyncPeer(peer)
+                       return fastSyncType
+               }
        }
 
        peer = bk.peers.BestPeer(consensus.SFFullNode)
        }
 
        peer = bk.peers.BestPeer(consensus.SFFullNode)
@@ -209,8 +206,7 @@ func (bk *blockKeeper) checkSyncType() int {
                return noNeedSync
        }
 
                return noNeedSync
        }
 
-       peerHeight := peer.Height()
-       if peerHeight > bestHeight {
+       if peer.Height() > bestHeight {
                bk.syncPeer = peer
                return regularSyncType
        }
                bk.syncPeer = peer
                return regularSyncType
        }
@@ -230,6 +226,8 @@ func (bk *blockKeeper) startSync() bool {
                        log.WithFields(log.Fields{"module": logModule, "err": err}).Warning("fail on regularBlockSync")
                        return false
                }
                        log.WithFields(log.Fields{"module": logModule, "err": err}).Warning("fail on regularBlockSync")
                        return false
                }
+       default:
+               return false
        }
 
        return true
        }
 
        return true
index 06a36d2..9472f21 100644 (file)
@@ -11,17 +11,108 @@ import (
        dbm "github.com/vapor/database/leveldb"
        "github.com/vapor/errors"
        msgs "github.com/vapor/netsync/messages"
        dbm "github.com/vapor/database/leveldb"
        "github.com/vapor/errors"
        msgs "github.com/vapor/netsync/messages"
+       "github.com/vapor/netsync/peers"
+       "github.com/vapor/protocol"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
        "github.com/vapor/test/mock"
        "github.com/vapor/testutil"
 )
 
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
        "github.com/vapor/test/mock"
        "github.com/vapor/testutil"
 )
 
+func TestCheckSyncType(t *testing.T) {
+       tmp, err := ioutil.TempDir(".", "")
+       if err != nil {
+               t.Fatalf("failed to create temporary data folder: %v", err)
+       }
+       fastSyncDB := dbm.NewDB("testdb", "leveldb", tmp)
+       defer func() {
+               fastSyncDB.Close()
+               os.RemoveAll(tmp)
+       }()
+
+       blocks := mockBlocks(nil, 50)
+       chain := mock.NewChain(nil)
+       chain.SetBestBlockHeader(&blocks[len(blocks)-1].BlockHeader)
+       for _, block := range blocks {
+               chain.SetBlockByHeight(block.Height, block)
+       }
+
+       type syncPeer struct {
+               peer               *P2PPeer
+               bestHeight         uint64
+               irreversibleHeight uint64
+       }
+
+       cases := []struct {
+               peers    []*syncPeer
+               syncType int
+       }{
+               {
+                       peers:    []*syncPeer{},
+                       syncType: noNeedSync,
+               },
+               {
+                       peers: []*syncPeer{
+                               {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 1000, irreversibleHeight: 500},
+                               {peer: &P2PPeer{id: "peer2", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 50, irreversibleHeight: 50},
+                       },
+                       syncType: fastSyncType,
+               },
+               {
+                       peers: []*syncPeer{
+                               {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 1000, irreversibleHeight: 100},
+                               {peer: &P2PPeer{id: "peer2", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 500, irreversibleHeight: 50},
+                       },
+                       syncType: regularSyncType,
+               },
+               {
+                       peers: []*syncPeer{
+                               {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 51, irreversibleHeight: 50},
+                       },
+                       syncType: regularSyncType,
+               },
+               {
+                       peers: []*syncPeer{
+                               {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 30, irreversibleHeight: 30},
+                       },
+                       syncType: noNeedSync,
+               },
+               {
+                       peers: []*syncPeer{
+                               {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode}, bestHeight: 1000, irreversibleHeight: 1000},
+                       },
+                       syncType: regularSyncType,
+               },
+               {
+                       peers: []*syncPeer{
+                               {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 1000, irreversibleHeight: 50},
+                               {peer: &P2PPeer{id: "peer2", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 800, irreversibleHeight: 800},
+                       },
+                       syncType: fastSyncType,
+               },
+       }
+
+       for i, c := range cases {
+               peers := peers.NewPeerSet(NewPeerSet())
+               blockKeeper := newBlockKeeper(chain, peers, fastSyncDB)
+               for _, syncPeer := range c.peers {
+                       blockKeeper.peers.AddPeer(syncPeer.peer)
+                       blockKeeper.peers.SetStatus(syncPeer.peer.id, syncPeer.bestHeight, nil)
+                       blockKeeper.peers.SetIrreversibleStatus(syncPeer.peer.id, syncPeer.irreversibleHeight, nil)
+               }
+               gotType := blockKeeper.checkSyncType()
+               if c.syncType != gotType {
+                       t.Errorf("case %d: got %d want %d", i, gotType, c.syncType)
+               }
+       }
+}
+
 func TestRegularBlockSync(t *testing.T) {
        baseChain := mockBlocks(nil, 50)
        chainX := append(baseChain, mockBlocks(baseChain[50], 60)...)
        chainY := append(baseChain, mockBlocks(baseChain[50], 70)...)
        chainZ := append(baseChain, mockBlocks(baseChain[50], 200)...)
 func TestRegularBlockSync(t *testing.T) {
        baseChain := mockBlocks(nil, 50)
        chainX := append(baseChain, mockBlocks(baseChain[50], 60)...)
        chainY := append(baseChain, mockBlocks(baseChain[50], 70)...)
        chainZ := append(baseChain, mockBlocks(baseChain[50], 200)...)
+       chainE := append(baseChain, mockErrorBlocks(baseChain[50], 200, 60)...)
 
        cases := []struct {
                syncTimeout time.Duration
 
        cases := []struct {
                syncTimeout time.Duration
@@ -58,6 +149,20 @@ func TestRegularBlockSync(t *testing.T) {
                        want:        chainZ[:180],
                        err:         nil,
                },
                        want:        chainZ[:180],
                        err:         nil,
                },
+               {
+                       syncTimeout: 0 * time.Second,
+                       aBlocks:     chainX[:52],
+                       bBlocks:     chainZ,
+                       want:        chainX[:52],
+                       err:         errRequestTimeout,
+               },
+               {
+                       syncTimeout: 30 * time.Second,
+                       aBlocks:     chainX[:52],
+                       bBlocks:     chainE,
+                       want:        chainE[:60],
+                       err:         protocol.ErrBadStateRoot,
+               },
        }
        tmp, err := ioutil.TempDir(".", "")
        if err != nil {
        }
        tmp, err := ioutil.TempDir(".", "")
        if err != nil {
@@ -84,6 +189,7 @@ func TestRegularBlockSync(t *testing.T) {
                        go A2B.postMan()
                }
 
                        go A2B.postMan()
                }
 
+               requireBlockTimeout = c.syncTimeout
                a.blockKeeper.syncPeer = a.peers.GetPeer("test node B")
                if err := a.blockKeeper.regularBlockSync(); errors.Root(err) != c.err {
                        t.Errorf("case %d: got %v want %v", i, err, c.err)
                a.blockKeeper.syncPeer = a.peers.GetPeer("test node B")
                if err := a.blockKeeper.regularBlockSync(); errors.Root(err) != c.err {
                        t.Errorf("case %d: got %v want %v", i, err, c.err)
@@ -308,11 +414,19 @@ func TestLocateBlocks(t *testing.T) {
                locator    []uint64
                stopHash   bc.Hash
                wantHeight []uint64
                locator    []uint64
                stopHash   bc.Hash
                wantHeight []uint64
+               wantErr    error
        }{
                {
                        locator:    []uint64{20},
                        stopHash:   blocks[100].Hash(),
                        wantHeight: []uint64{20, 21, 22, 23, 24},
        }{
                {
                        locator:    []uint64{20},
                        stopHash:   blocks[100].Hash(),
                        wantHeight: []uint64{20, 21, 22, 23, 24},
+                       wantErr:    nil,
+               },
+               {
+                       locator:    []uint64{20},
+                       stopHash:   bc.NewHash([32]byte{0x01, 0x02}),
+                       wantHeight: []uint64{},
+                       wantErr:    mock.ErrFoundHeaderByHash,
                },
        }
 
                },
        }
 
@@ -334,7 +448,11 @@ func TestLocateBlocks(t *testing.T) {
                        want = append(want, blocks[i])
                }
 
                        want = append(want, blocks[i])
                }
 
-               got, _ := bk.locateBlocks(locator, &c.stopHash)
+               got, err := bk.locateBlocks(locator, &c.stopHash)
+               if err != c.wantErr {
+                       t.Errorf("case %d: got %v want err = %v", i, err, c.wantErr)
+               }
+
                if !testutil.DeepEqual(got, want) {
                        t.Errorf("case %d: got %v want %v", i, got, want)
                }
                if !testutil.DeepEqual(got, want) {
                        t.Errorf("case %d: got %v want %v", i, got, want)
                }
@@ -358,7 +476,7 @@ func TestLocateHeaders(t *testing.T) {
                stopHash    *bc.Hash
                skip        uint64
                wantHeight  []uint64
                stopHash    *bc.Hash
                skip        uint64
                wantHeight  []uint64
-               err         bool
+               err         error
        }{
                {
                        chainHeight: 100,
        }{
                {
                        chainHeight: 100,
@@ -366,7 +484,7 @@ func TestLocateHeaders(t *testing.T) {
                        stopHash:    &blocksHash[100],
                        skip:        0,
                        wantHeight:  []uint64{90, 91, 92, 93, 94, 95, 96, 97, 98, 99},
                        stopHash:    &blocksHash[100],
                        skip:        0,
                        wantHeight:  []uint64{90, 91, 92, 93, 94, 95, 96, 97, 98, 99},
-                       err:         false,
+                       err:         nil,
                },
                {
                        chainHeight: 100,
                },
                {
                        chainHeight: 100,
@@ -374,28 +492,28 @@ func TestLocateHeaders(t *testing.T) {
                        stopHash:    &blocksHash[24],
                        skip:        0,
                        wantHeight:  []uint64{20, 21, 22, 23, 24},
                        stopHash:    &blocksHash[24],
                        skip:        0,
                        wantHeight:  []uint64{20, 21, 22, 23, 24},
-                       err:         false,
+                       err:         nil,
                },
                {
                        chainHeight: 100,
                        locator:     []uint64{20},
                        stopHash:    &blocksHash[20],
                        wantHeight:  []uint64{20},
                },
                {
                        chainHeight: 100,
                        locator:     []uint64{20},
                        stopHash:    &blocksHash[20],
                        wantHeight:  []uint64{20},
-                       err:         false,
+                       err:         nil,
                },
                {
                        chainHeight: 100,
                        locator:     []uint64{20},
                        stopHash:    &blocksHash[120],
                        wantHeight:  []uint64{},
                },
                {
                        chainHeight: 100,
                        locator:     []uint64{20},
                        stopHash:    &blocksHash[120],
                        wantHeight:  []uint64{},
-                       err:         false,
+                       err:         mock.ErrFoundHeaderByHash,
                },
                {
                        chainHeight: 100,
                        locator:     []uint64{120, 70},
                        stopHash:    &blocksHash[78],
                        wantHeight:  []uint64{70, 71, 72, 73, 74, 75, 76, 77, 78},
                },
                {
                        chainHeight: 100,
                        locator:     []uint64{120, 70},
                        stopHash:    &blocksHash[78],
                        wantHeight:  []uint64{70, 71, 72, 73, 74, 75, 76, 77, 78},
-                       err:         false,
+                       err:         nil,
                },
                {
                        chainHeight: 100,
                },
                {
                        chainHeight: 100,
@@ -403,7 +521,7 @@ func TestLocateHeaders(t *testing.T) {
                        stopHash:    &blocksHash[10],
                        skip:        10,
                        wantHeight:  []uint64{},
                        stopHash:    &blocksHash[10],
                        skip:        10,
                        wantHeight:  []uint64{},
-                       err:         false,
+                       err:         nil,
                },
                {
                        chainHeight: 100,
                },
                {
                        chainHeight: 100,
@@ -411,7 +529,7 @@ func TestLocateHeaders(t *testing.T) {
                        stopHash:    &blocksHash[80],
                        skip:        10,
                        wantHeight:  []uint64{15, 26, 37, 48, 59, 70, 80},
                        stopHash:    &blocksHash[80],
                        skip:        10,
                        wantHeight:  []uint64{15, 26, 37, 48, 59, 70, 80},
-                       err:         false,
+                       err:         nil,
                },
                {
                        chainHeight: 100,
                },
                {
                        chainHeight: 100,
@@ -419,7 +537,7 @@ func TestLocateHeaders(t *testing.T) {
                        stopHash:    &blocksHash[100],
                        skip:        9,
                        wantHeight:  []uint64{0, 10, 20, 30, 40, 50, 60, 70, 80, 90},
                        stopHash:    &blocksHash[100],
                        skip:        9,
                        wantHeight:  []uint64{0, 10, 20, 30, 40, 50, 60, 70, 80, 90},
-                       err:         false,
+                       err:         nil,
                },
        }
 
                },
        }
 
@@ -442,7 +560,7 @@ func TestLocateHeaders(t *testing.T) {
                }
 
                got, err := bk.locateHeaders(locator, c.stopHash, c.skip, maxNumOfHeadersPerMsg)
                }
 
                got, err := bk.locateHeaders(locator, c.stopHash, c.skip, maxNumOfHeadersPerMsg)
-               if err != nil != c.err {
+               if err != c.err {
                        t.Errorf("case %d: got %v want err = %v", i, err, c.err)
                }
                if !testutil.DeepEqual(got, want) {
                        t.Errorf("case %d: got %v want err = %v", i, err, c.err)
                }
                if !testutil.DeepEqual(got, want) {
index 5bc2075..7663dc8 100644 (file)
@@ -8,6 +8,8 @@ import (
        "time"
 
        dbm "github.com/vapor/database/leveldb"
        "time"
 
        dbm "github.com/vapor/database/leveldb"
+       "github.com/vapor/netsync/peers"
+       "github.com/vapor/protocol/bc/types"
        "github.com/vapor/test/mock"
 )
 
        "github.com/vapor/test/mock"
 )
 
@@ -21,30 +23,52 @@ func TestBlockProcess(t *testing.T) {
        testDB := dbm.NewDB("testdb", "leveldb", tmp)
        defer testDB.Close()
 
        testDB := dbm.NewDB("testdb", "leveldb", tmp)
        defer testDB.Close()
 
+       cases := []struct {
+               blocks      []*types.Block
+               startHeight uint64
+               stopHeight  uint64
+       }{
+               {
+                       blocks:      mockBlocks(nil, 200),
+                       startHeight: 100,
+                       stopHeight:  200,
+               },
+               {
+                       blocks:      mockBlocks(nil, 200),
+                       startHeight: 110,
+                       stopHeight:  100,
+               },
+               {
+                       blocks:      mockErrorBlocks(nil, 200, 150),
+                       startHeight: 100,
+                       stopHeight:  149,
+               },
+       }
        s := newStorage(testDB)
        mockChain := mock.NewChain(nil)
        s := newStorage(testDB)
        mockChain := mock.NewChain(nil)
-       blockNum := 200
-       blocks := mockBlocks(nil, uint64(blockNum))
-       for i := 0; i <= blockNum/2; i++ {
-               mockChain.SetBlockByHeight(uint64(i), blocks[i])
-               mockChain.SetBestBlockHeader(&blocks[i].BlockHeader)
-       }
+       for i, c := range cases {
+               for i := 0; i <= len(c.blocks)/2; i++ {
+                       mockChain.SetBlockByHeight(uint64(i), c.blocks[i])
+                       mockChain.SetBestBlockHeader(&c.blocks[i].BlockHeader)
+               }
 
 
-       if err := s.writeBlocks("testPeer", blocks); err != nil {
-               t.Fatal(err)
-       }
+               if err := s.writeBlocks("testPeer", c.blocks); err != nil {
+                       t.Fatal(err)
+               }
+
+               bp := newBlockProcessor(mockChain, s, peers.NewPeerSet(nil))
+               downloadNotifyCh := make(chan struct{}, 1)
+               ProcessStopCh := make(chan struct{})
+               var wg sync.WaitGroup
+               go func() {
+                       time.Sleep(1 * time.Second)
+                       close(downloadNotifyCh)
+               }()
+               wg.Add(1)
 
 
-       bp := newBlockProcessor(mockChain, s, nil)
-       downloadNotifyCh := make(chan struct{}, 1)
-       ProcessStopCh := make(chan struct{})
-       var wg sync.WaitGroup
-       go func() {
-               time.Sleep(1 * time.Second)
-               close(downloadNotifyCh)
-       }()
-       wg.Add(1)
-       bp.process(downloadNotifyCh, ProcessStopCh, uint64(blockNum/2), &wg)
-       if bp.chain.BestBlockHeight() != uint64(blockNum) {
-               t.Fatalf("TestBlockProcess fail: got %d want %d", bp.chain.BestBlockHeight(), blockNum)
+               bp.process(downloadNotifyCh, ProcessStopCh, c.startHeight, &wg)
+               if bp.chain.BestBlockHeight() != c.stopHeight {
+                       t.Fatalf("TestBlockProcess index: %d fail: got %d want %d", i, bp.chain.BestBlockHeight(), c.stopHeight)
+               }
        }
 }
        }
 }
index 63b6a2f..4a3badd 100644 (file)
@@ -161,6 +161,33 @@ func mockBlocks(startBlock *types.Block, height uint64) []*types.Block {
        return blocks
 }
 
        return blocks
 }
 
+func mockErrorBlocks(startBlock *types.Block, height uint64, errBlockHeight uint64) []*types.Block {
+       blocks := []*types.Block{}
+       indexBlock := &types.Block{}
+       if startBlock == nil {
+               indexBlock = &types.Block{BlockHeader: types.BlockHeader{Version: uint64(rand.Uint32())}}
+               blocks = append(blocks, indexBlock)
+       } else {
+               indexBlock = startBlock
+       }
+
+       for indexBlock.Height < height {
+               block := &types.Block{
+                       BlockHeader: types.BlockHeader{
+                               Height:            indexBlock.Height + 1,
+                               PreviousBlockHash: indexBlock.Hash(),
+                               Version:           uint64(rand.Uint32()),
+                       },
+               }
+               if block.Height == errBlockHeight {
+                       block.TransactionsMerkleRoot = bc.NewHash([32]byte{0x1})
+               }
+               blocks = append(blocks, block)
+               indexBlock = block
+       }
+       return blocks
+}
+
 func mockSync(blocks []*types.Block, mempool *mock.Mempool, fastSyncDB dbm.DB) *Manager {
        chain := mock.NewChain(mempool)
        peers := peers.NewPeerSet(NewPeerSet())
 func mockSync(blocks []*types.Block, mempool *mock.Mempool, fastSyncDB dbm.DB) *Manager {
        chain := mock.NewChain(mempool)
        peers := peers.NewPeerSet(NewPeerSet())
index 431de06..ef90812 100644 (file)
@@ -673,6 +673,15 @@ func (ps *PeerSet) SetStatus(peerID string, height uint64, hash *bc.Hash) {
        peer.SetBestStatus(height, hash)
 }
 
        peer.SetBestStatus(height, hash)
 }
 
+func (ps *PeerSet) SetIrreversibleStatus(peerID string, height uint64, hash *bc.Hash) {
+       peer := ps.GetPeer(peerID)
+       if peer == nil {
+               return
+       }
+
+       peer.SetIrreversibleStatus(height, hash)
+}
+
 func (ps *PeerSet) Size() int {
        ps.mtx.RLock()
        defer ps.mtx.RUnlock()
 func (ps *PeerSet) Size() int {
        ps.mtx.RLock()
        defer ps.mtx.RUnlock()
index 700891f..69ef7c4 100644 (file)
@@ -4,10 +4,16 @@ import (
        "errors"
        "math/rand"
 
        "errors"
        "math/rand"
 
+       "github.com/vapor/protocol"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
 )
 
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
 )
 
+var (
+       ErrFoundHeaderByHash   = errors.New("can't find header by hash")
+       ErrFoundHeaderByHeight = errors.New("can't find header by height")
+)
+
 type mempool interface {
        AddTx(tx *types.Tx)
 }
 type mempool interface {
        AddTx(tx *types.Tx)
 }
@@ -64,7 +70,7 @@ func (c *Chain) GetBlockByHeight(height uint64) (*types.Block, error) {
 func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
        block, ok := c.blockMap[*hash]
        if !ok {
 func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
        block, ok := c.blockMap[*hash]
        if !ok {
-               return nil, errors.New("can't find block")
+               return nil, ErrFoundHeaderByHash
        }
        return &block.BlockHeader, nil
 }
        }
        return &block.BlockHeader, nil
 }
@@ -72,7 +78,7 @@ func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
 func (c *Chain) GetHeaderByHeight(height uint64) (*types.BlockHeader, error) {
        block, ok := c.heightMap[height]
        if !ok {
 func (c *Chain) GetHeaderByHeight(height uint64) (*types.BlockHeader, error) {
        block, ok := c.heightMap[height]
        if !ok {
-               return nil, errors.New("can't find block")
+               return nil, ErrFoundHeaderByHeight
        }
        return &block.BlockHeader, nil
 }
        }
        return &block.BlockHeader, nil
 }
@@ -107,6 +113,10 @@ func (c *Chain) InMainChain(hash bc.Hash) bool {
 }
 
 func (c *Chain) ProcessBlock(block *types.Block) (bool, error) {
 }
 
 func (c *Chain) ProcessBlock(block *types.Block) (bool, error) {
+       if block.TransactionsMerkleRoot == bc.NewHash([32]byte{0x1}) {
+               return false, protocol.ErrBadStateRoot
+       }
+
        if c.bestBlockHeader.Hash() == block.PreviousBlockHash {
                c.heightMap[block.Height] = block
                c.blockMap[block.Hash()] = block
        if c.bestBlockHeader.Hash() == block.PreviousBlockHash {
                c.heightMap[block.Height] = block
                c.blockMap[block.Hash()] = block