• R/O
  • HTTP
  • SSH
  • HTTPS

vapor: Commit

Golang implemented sidechain for Bytom


Commit MetaInfo

Revisionbe230601dbfe48d6d088854d553e4f71e7d435ff (tree)
Time2019-07-29 20:28:42
AuthorYahtoo Ma <yahtoo.ma@gmai...>
CommiterYahtoo Ma

Log Message

netsync add test case

Change Summary

Incremental Difference

--- a/netsync/chainmgr/block_keeper.go
+++ b/netsync/chainmgr/block_keeper.go
@@ -112,7 +112,7 @@ func (bk *blockKeeper) locateHeaders(locator []*bc.Hash, stopHash *bc.Hash, skip
112112 headers := make([]*types.BlockHeader, 0)
113113 stopHeader, err := bk.chain.GetHeaderByHash(stopHash)
114114 if err != nil {
115- return headers, nil
115+ return headers, err
116116 }
117117
118118 if !bk.chain.InMainChain(*stopHash) || stopHeader.Height < startHeader.Height {
@@ -191,16 +191,13 @@ func (bk *blockKeeper) start() {
191191 }
192192
193193 func (bk *blockKeeper) checkSyncType() int {
194- peer := bk.peers.BestIrreversiblePeer(consensus.SFFullNode | consensus.SFFastSync)
195- if peer == nil {
196- log.WithFields(log.Fields{"module": logModule}).Debug("can't find fast sync peer")
197- return noNeedSync
198- }
199-
200194 bestHeight := bk.chain.BestBlockHeight()
201- if peerIrreversibleHeight := peer.IrreversibleHeight(); peerIrreversibleHeight >= bestHeight+minGapStartFastSync {
202- bk.fastSync.setSyncPeer(peer)
203- return fastSyncType
195+ peer := bk.peers.BestIrreversiblePeer(consensus.SFFullNode | consensus.SFFastSync)
196+ if peer != nil {
197+ if peerIrreversibleHeight := peer.IrreversibleHeight(); peerIrreversibleHeight >= bestHeight+minGapStartFastSync {
198+ bk.fastSync.setSyncPeer(peer)
199+ return fastSyncType
200+ }
204201 }
205202
206203 peer = bk.peers.BestPeer(consensus.SFFullNode)
@@ -209,8 +206,7 @@ func (bk *blockKeeper) checkSyncType() int {
209206 return noNeedSync
210207 }
211208
212- peerHeight := peer.Height()
213- if peerHeight > bestHeight {
209+ if peer.Height() > bestHeight {
214210 bk.syncPeer = peer
215211 return regularSyncType
216212 }
@@ -230,6 +226,8 @@ func (bk *blockKeeper) startSync() bool {
230226 log.WithFields(log.Fields{"module": logModule, "err": err}).Warning("fail on regularBlockSync")
231227 return false
232228 }
229+ default:
230+ return false
233231 }
234232
235233 return true
--- a/netsync/chainmgr/block_keeper_test.go
+++ b/netsync/chainmgr/block_keeper_test.go
@@ -11,17 +11,108 @@ import (
1111 dbm "github.com/vapor/database/leveldb"
1212 "github.com/vapor/errors"
1313 msgs "github.com/vapor/netsync/messages"
14+ "github.com/vapor/netsync/peers"
15+ "github.com/vapor/protocol"
1416 "github.com/vapor/protocol/bc"
1517 "github.com/vapor/protocol/bc/types"
1618 "github.com/vapor/test/mock"
1719 "github.com/vapor/testutil"
1820 )
1921
22+func TestCheckSyncType(t *testing.T) {
23+ tmp, err := ioutil.TempDir(".", "")
24+ if err != nil {
25+ t.Fatalf("failed to create temporary data folder: %v", err)
26+ }
27+ fastSyncDB := dbm.NewDB("testdb", "leveldb", tmp)
28+ defer func() {
29+ fastSyncDB.Close()
30+ os.RemoveAll(tmp)
31+ }()
32+
33+ blocks := mockBlocks(nil, 50)
34+ chain := mock.NewChain(nil)
35+ chain.SetBestBlockHeader(&blocks[len(blocks)-1].BlockHeader)
36+ for _, block := range blocks {
37+ chain.SetBlockByHeight(block.Height, block)
38+ }
39+
40+ type syncPeer struct {
41+ peer *P2PPeer
42+ bestHeight uint64
43+ irreversibleHeight uint64
44+ }
45+
46+ cases := []struct {
47+ peers []*syncPeer
48+ syncType int
49+ }{
50+ {
51+ peers: []*syncPeer{},
52+ syncType: noNeedSync,
53+ },
54+ {
55+ peers: []*syncPeer{
56+ {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 1000, irreversibleHeight: 500},
57+ {peer: &P2PPeer{id: "peer2", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 50, irreversibleHeight: 50},
58+ },
59+ syncType: fastSyncType,
60+ },
61+ {
62+ peers: []*syncPeer{
63+ {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 1000, irreversibleHeight: 100},
64+ {peer: &P2PPeer{id: "peer2", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 500, irreversibleHeight: 50},
65+ },
66+ syncType: regularSyncType,
67+ },
68+ {
69+ peers: []*syncPeer{
70+ {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 51, irreversibleHeight: 50},
71+ },
72+ syncType: regularSyncType,
73+ },
74+ {
75+ peers: []*syncPeer{
76+ {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 30, irreversibleHeight: 30},
77+ },
78+ syncType: noNeedSync,
79+ },
80+ {
81+ peers: []*syncPeer{
82+ {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode}, bestHeight: 1000, irreversibleHeight: 1000},
83+ },
84+ syncType: regularSyncType,
85+ },
86+ {
87+ peers: []*syncPeer{
88+ {peer: &P2PPeer{id: "peer1", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 1000, irreversibleHeight: 50},
89+ {peer: &P2PPeer{id: "peer2", flag: consensus.SFFullNode | consensus.SFFastSync}, bestHeight: 800, irreversibleHeight: 800},
90+ },
91+ syncType: fastSyncType,
92+ },
93+ }
94+
95+ for i, c := range cases {
96+ peers := peers.NewPeerSet(NewPeerSet())
97+ blockKeeper := newBlockKeeper(chain, peers, fastSyncDB)
98+ for _, syncPeer := range c.peers {
99+ blockKeeper.peers.AddPeer(syncPeer.peer)
100+ blockKeeper.peers.SetStatus(syncPeer.peer.id, syncPeer.bestHeight, nil)
101+ blockKeeper.peers.SetIrreversibleStatus(syncPeer.peer.id, syncPeer.irreversibleHeight, nil)
102+ }
103+ gotType := blockKeeper.checkSyncType()
104+ if c.syncType != gotType {
105+ t.Errorf("case %d: got %d want %d", i, gotType, c.syncType)
106+ }
107+ }
108+}
109+
20110 func TestRegularBlockSync(t *testing.T) {
21111 baseChain := mockBlocks(nil, 50)
22112 chainX := append(baseChain, mockBlocks(baseChain[50], 60)...)
23113 chainY := append(baseChain, mockBlocks(baseChain[50], 70)...)
24114 chainZ := append(baseChain, mockBlocks(baseChain[50], 200)...)
115+ chainE := append(baseChain, mockErrorBlocks(baseChain[50], 200, 60)...)
25116
26117 cases := []struct {
27118 syncTimeout time.Duration
@@ -58,6 +149,20 @@ func TestRegularBlockSync(t *testing.T) {
58149 want: chainZ[:180],
59150 err: nil,
60151 },
152+ {
153+ syncTimeout: 0 * time.Second,
154+ aBlocks: chainX[:52],
155+ bBlocks: chainZ,
156+ want: chainX[:52],
157+ err: errRequestTimeout,
158+ },
159+ {
160+ syncTimeout: 30 * time.Second,
161+ aBlocks: chainX[:52],
162+ bBlocks: chainE,
163+ want: chainE[:60],
164+ err: protocol.ErrBadStateRoot,
165+ },
61166 }
62167 tmp, err := ioutil.TempDir(".", "")
63168 if err != nil {
@@ -84,6 +189,7 @@ func TestRegularBlockSync(t *testing.T) {
84189 go A2B.postMan()
85190 }
86191
192+ requireBlockTimeout = c.syncTimeout
87193 a.blockKeeper.syncPeer = a.peers.GetPeer("test node B")
88194 if err := a.blockKeeper.regularBlockSync(); errors.Root(err) != c.err {
89195 t.Errorf("case %d: got %v want %v", i, err, c.err)
@@ -308,11 +414,19 @@ func TestLocateBlocks(t *testing.T) {
308414 locator []uint64
309415 stopHash bc.Hash
310416 wantHeight []uint64
417+ wantErr error
311418 }{
312419 {
313420 locator: []uint64{20},
314421 stopHash: blocks[100].Hash(),
315422 wantHeight: []uint64{20, 21, 22, 23, 24},
423+ wantErr: nil,
424+ },
425+ {
426+ locator: []uint64{20},
427+ stopHash: bc.NewHash([32]byte{0x01, 0x02}),
428+ wantHeight: []uint64{},
429+ wantErr: mock.ErrFoundHeaderByHash,
316430 },
317431 }
318432
@@ -334,7 +448,11 @@ func TestLocateBlocks(t *testing.T) {
334448 want = append(want, blocks[i])
335449 }
336450
337- got, _ := bk.locateBlocks(locator, &c.stopHash)
451+ got, err := bk.locateBlocks(locator, &c.stopHash)
452+ if err != c.wantErr {
453+ t.Errorf("case %d: got %v want err = %v", i, err, c.wantErr)
454+ }
455+
338456 if !testutil.DeepEqual(got, want) {
339457 t.Errorf("case %d: got %v want %v", i, got, want)
340458 }
@@ -358,7 +476,7 @@ func TestLocateHeaders(t *testing.T) {
358476 stopHash *bc.Hash
359477 skip uint64
360478 wantHeight []uint64
361- err bool
479+ err error
362480 }{
363481 {
364482 chainHeight: 100,
@@ -366,7 +484,7 @@ func TestLocateHeaders(t *testing.T) {
366484 stopHash: &blocksHash[100],
367485 skip: 0,
368486 wantHeight: []uint64{90, 91, 92, 93, 94, 95, 96, 97, 98, 99},
369- err: false,
487+ err: nil,
370488 },
371489 {
372490 chainHeight: 100,
@@ -374,28 +492,28 @@ func TestLocateHeaders(t *testing.T) {
374492 stopHash: &blocksHash[24],
375493 skip: 0,
376494 wantHeight: []uint64{20, 21, 22, 23, 24},
377- err: false,
495+ err: nil,
378496 },
379497 {
380498 chainHeight: 100,
381499 locator: []uint64{20},
382500 stopHash: &blocksHash[20],
383501 wantHeight: []uint64{20},
384- err: false,
502+ err: nil,
385503 },
386504 {
387505 chainHeight: 100,
388506 locator: []uint64{20},
389507 stopHash: &blocksHash[120],
390508 wantHeight: []uint64{},
391- err: false,
509+ err: mock.ErrFoundHeaderByHash,
392510 },
393511 {
394512 chainHeight: 100,
395513 locator: []uint64{120, 70},
396514 stopHash: &blocksHash[78],
397515 wantHeight: []uint64{70, 71, 72, 73, 74, 75, 76, 77, 78},
398- err: false,
516+ err: nil,
399517 },
400518 {
401519 chainHeight: 100,
@@ -403,7 +521,7 @@ func TestLocateHeaders(t *testing.T) {
403521 stopHash: &blocksHash[10],
404522 skip: 10,
405523 wantHeight: []uint64{},
406- err: false,
524+ err: nil,
407525 },
408526 {
409527 chainHeight: 100,
@@ -411,7 +529,7 @@ func TestLocateHeaders(t *testing.T) {
411529 stopHash: &blocksHash[80],
412530 skip: 10,
413531 wantHeight: []uint64{15, 26, 37, 48, 59, 70, 80},
414- err: false,
532+ err: nil,
415533 },
416534 {
417535 chainHeight: 100,
@@ -419,7 +537,7 @@ func TestLocateHeaders(t *testing.T) {
419537 stopHash: &blocksHash[100],
420538 skip: 9,
421539 wantHeight: []uint64{0, 10, 20, 30, 40, 50, 60, 70, 80, 90},
422- err: false,
540+ err: nil,
423541 },
424542 }
425543
@@ -442,7 +560,7 @@ func TestLocateHeaders(t *testing.T) {
442560 }
443561
444562 got, err := bk.locateHeaders(locator, c.stopHash, c.skip, maxNumOfHeadersPerMsg)
445- if err != nil != c.err {
563+ if err != c.err {
446564 t.Errorf("case %d: got %v want err = %v", i, err, c.err)
447565 }
448566 if !testutil.DeepEqual(got, want) {
--- a/netsync/chainmgr/block_process_test.go
+++ b/netsync/chainmgr/block_process_test.go
@@ -8,6 +8,8 @@ import (
88 "time"
99
1010 dbm "github.com/vapor/database/leveldb"
11+ "github.com/vapor/netsync/peers"
12+ "github.com/vapor/protocol/bc/types"
1113 "github.com/vapor/test/mock"
1214 )
1315
@@ -21,30 +23,52 @@ func TestBlockProcess(t *testing.T) {
2123 testDB := dbm.NewDB("testdb", "leveldb", tmp)
2224 defer testDB.Close()
2325
26+ cases := []struct {
27+ blocks []*types.Block
28+ startHeight uint64
29+ stopHeight uint64
30+ }{
31+ {
32+ blocks: mockBlocks(nil, 200),
33+ startHeight: 100,
34+ stopHeight: 200,
35+ },
36+ {
37+ blocks: mockBlocks(nil, 200),
38+ startHeight: 110,
39+ stopHeight: 100,
40+ },
41+ {
42+ blocks: mockErrorBlocks(nil, 200, 150),
43+ startHeight: 100,
44+ stopHeight: 149,
45+ },
46+ }
2447 s := newStorage(testDB)
2548 mockChain := mock.NewChain(nil)
26- blockNum := 200
27- blocks := mockBlocks(nil, uint64(blockNum))
28- for i := 0; i <= blockNum/2; i++ {
29- mockChain.SetBlockByHeight(uint64(i), blocks[i])
30- mockChain.SetBestBlockHeader(&blocks[i].BlockHeader)
31- }
49+ for i, c := range cases {
50+ for i := 0; i <= len(c.blocks)/2; i++ {
51+ mockChain.SetBlockByHeight(uint64(i), c.blocks[i])
52+ mockChain.SetBestBlockHeader(&c.blocks[i].BlockHeader)
53+ }
3254
33- if err := s.writeBlocks("testPeer", blocks); err != nil {
34- t.Fatal(err)
35- }
55+ if err := s.writeBlocks("testPeer", c.blocks); err != nil {
56+ t.Fatal(err)
57+ }
58+
59+ bp := newBlockProcessor(mockChain, s, peers.NewPeerSet(nil))
60+ downloadNotifyCh := make(chan struct{}, 1)
61+ ProcessStopCh := make(chan struct{})
62+ var wg sync.WaitGroup
63+ go func() {
64+ time.Sleep(1 * time.Second)
65+ close(downloadNotifyCh)
66+ }()
67+ wg.Add(1)
3668
37- bp := newBlockProcessor(mockChain, s, nil)
38- downloadNotifyCh := make(chan struct{}, 1)
39- ProcessStopCh := make(chan struct{})
40- var wg sync.WaitGroup
41- go func() {
42- time.Sleep(1 * time.Second)
43- close(downloadNotifyCh)
44- }()
45- wg.Add(1)
46- bp.process(downloadNotifyCh, ProcessStopCh, uint64(blockNum/2), &wg)
47- if bp.chain.BestBlockHeight() != uint64(blockNum) {
48- t.Fatalf("TestBlockProcess fail: got %d want %d", bp.chain.BestBlockHeight(), blockNum)
69+ bp.process(downloadNotifyCh, ProcessStopCh, c.startHeight, &wg)
70+ if bp.chain.BestBlockHeight() != c.stopHeight {
71+ t.Fatalf("TestBlockProcess index: %d fail: got %d want %d", i, bp.chain.BestBlockHeight(), c.stopHeight)
72+ }
4973 }
5074 }
--- a/netsync/chainmgr/tool_test.go
+++ b/netsync/chainmgr/tool_test.go
@@ -161,6 +161,33 @@ func mockBlocks(startBlock *types.Block, height uint64) []*types.Block {
161161 return blocks
162162 }
163163
164+func mockErrorBlocks(startBlock *types.Block, height uint64, errBlockHeight uint64) []*types.Block {
165+ blocks := []*types.Block{}
166+ indexBlock := &types.Block{}
167+ if startBlock == nil {
168+ indexBlock = &types.Block{BlockHeader: types.BlockHeader{Version: uint64(rand.Uint32())}}
169+ blocks = append(blocks, indexBlock)
170+ } else {
171+ indexBlock = startBlock
172+ }
173+
174+ for indexBlock.Height < height {
175+ block := &types.Block{
176+ BlockHeader: types.BlockHeader{
177+ Height: indexBlock.Height + 1,
178+ PreviousBlockHash: indexBlock.Hash(),
179+ Version: uint64(rand.Uint32()),
180+ },
181+ }
182+ if block.Height == errBlockHeight {
183+ block.TransactionsMerkleRoot = bc.NewHash([32]byte{0x1})
184+ }
185+ blocks = append(blocks, block)
186+ indexBlock = block
187+ }
188+ return blocks
189+}
190+
164191 func mockSync(blocks []*types.Block, mempool *mock.Mempool, fastSyncDB dbm.DB) *Manager {
165192 chain := mock.NewChain(mempool)
166193 peers := peers.NewPeerSet(NewPeerSet())
--- a/netsync/peers/peer.go
+++ b/netsync/peers/peer.go
@@ -673,6 +673,15 @@ func (ps *PeerSet) SetStatus(peerID string, height uint64, hash *bc.Hash) {
673673 peer.SetBestStatus(height, hash)
674674 }
675675
676+func (ps *PeerSet) SetIrreversibleStatus(peerID string, height uint64, hash *bc.Hash) {
677+ peer := ps.GetPeer(peerID)
678+ if peer == nil {
679+ return
680+ }
681+
682+ peer.SetIrreversibleStatus(height, hash)
683+}
684+
676685 func (ps *PeerSet) Size() int {
677686 ps.mtx.RLock()
678687 defer ps.mtx.RUnlock()
--- a/test/mock/chain.go
+++ b/test/mock/chain.go
@@ -4,10 +4,16 @@ import (
44 "errors"
55 "math/rand"
66
7+ "github.com/vapor/protocol"
78 "github.com/vapor/protocol/bc"
89 "github.com/vapor/protocol/bc/types"
910 )
1011
12+var (
13+ ErrFoundHeaderByHash = errors.New("can't find header by hash")
14+ ErrFoundHeaderByHeight = errors.New("can't find header by height")
15+)
16+
1117 type mempool interface {
1218 AddTx(tx *types.Tx)
1319 }
@@ -64,7 +70,7 @@ func (c *Chain) GetBlockByHeight(height uint64) (*types.Block, error) {
6470 func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
6571 block, ok := c.blockMap[*hash]
6672 if !ok {
67- return nil, errors.New("can't find block")
73+ return nil, ErrFoundHeaderByHash
6874 }
6975 return &block.BlockHeader, nil
7076 }
@@ -72,7 +78,7 @@ func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
7278 func (c *Chain) GetHeaderByHeight(height uint64) (*types.BlockHeader, error) {
7379 block, ok := c.heightMap[height]
7480 if !ok {
75- return nil, errors.New("can't find block")
81+ return nil, ErrFoundHeaderByHeight
7682 }
7783 return &block.BlockHeader, nil
7884 }
@@ -107,6 +113,10 @@ func (c *Chain) InMainChain(hash bc.Hash) bool {
107113 }
108114
109115 func (c *Chain) ProcessBlock(block *types.Block) (bool, error) {
116+ if block.TransactionsMerkleRoot == bc.NewHash([32]byte{0x1}) {
117+ return false, protocol.ErrBadStateRoot
118+ }
119+
110120 if c.bestBlockHeader.Hash() == block.PreviousBlockHash {
111121 c.heightMap[block.Height] = block
112122 c.blockMap[block.Hash()] = block
Show on old repository browser