9 "github.com/vapor/consensus"
10 dbm "github.com/vapor/database/leveldb"
11 "github.com/vapor/errors"
12 "github.com/vapor/protocol/bc"
13 "github.com/vapor/protocol/bc/types"
14 "github.com/vapor/test/mock"
15 "github.com/vapor/testutil"
18 func TestBlockLocator(t *testing.T) {
19 blocks := mockBlocks(nil, 500)
26 wantHeight: []uint64{0},
30 wantHeight: []uint64{1, 0},
34 wantHeight: []uint64{7, 6, 5, 4, 3, 2, 1, 0},
38 wantHeight: []uint64{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
42 wantHeight: []uint64{100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 89, 85, 77, 61, 29, 0},
46 wantHeight: []uint64{500, 499, 498, 497, 496, 495, 494, 493, 492, 491, 489, 485, 477, 461, 429, 365, 237, 0},
50 for i, c := range cases {
51 mockChain := mock.NewChain(nil)
52 fs := &fastSync{chain: mockChain}
53 mockChain.SetBestBlockHeader(&blocks[c.bestHeight].BlockHeader)
54 for i := uint64(0); i <= c.bestHeight; i++ {
55 mockChain.SetBlockByHeight(i, blocks[i])
59 for _, i := range c.wantHeight {
60 hash := blocks[i].Hash()
61 want = append(want, &hash)
64 if got := fs.blockLocator(); !testutil.DeepEqual(got, want) {
65 t.Errorf("case %d: got %v want %v", i, got, want)
70 func TestFastBlockSync(t *testing.T) {
71 tmp, err := ioutil.TempDir(".", "")
73 t.Fatalf("failed to create temporary data folder: %v", err)
75 testDBA := dbm.NewDB("testdba", "leveldb", tmp)
76 testDBB := dbm.NewDB("testdbb", "leveldb", tmp)
83 maxSizeOfSyncSkeleton = 11
84 numOfBlocksSkeletonGap = 10
85 maxNumOfBlocksPerSync = numOfBlocksSkeletonGap * uint64(maxSizeOfSyncSkeleton-1)
86 fastSyncPivotGap = uint64(5)
87 minGapStartFastSync = uint64(6)
90 maxSizeOfSyncSkeleton = 11
91 numOfBlocksSkeletonGap = maxNumOfBlocksPerMsg
92 maxNumOfBlocksPerSync = numOfBlocksSkeletonGap * uint64(maxSizeOfSyncSkeleton-1)
93 fastSyncPivotGap = uint64(64)
94 minGapStartFastSync = uint64(128)
95 requireHeadersTimeout = 30 * time.Second
98 baseChain := mockBlocks(nil, 300)
101 syncTimeout time.Duration
102 aBlocks []*types.Block
103 bBlocks []*types.Block
108 syncTimeout: 30 * time.Second,
109 aBlocks: baseChain[:50],
110 bBlocks: baseChain[:301],
111 want: baseChain[:150],
115 syncTimeout: 30 * time.Second,
116 aBlocks: baseChain[:2],
117 bBlocks: baseChain[:300],
118 want: baseChain[:102],
122 syncTimeout: 30 * time.Second,
123 aBlocks: baseChain[:2],
124 bBlocks: baseChain[:53],
125 want: baseChain[:48],
129 syncTimeout: 30 * time.Second,
130 aBlocks: baseChain[:2],
131 bBlocks: baseChain[:53],
132 want: baseChain[:48],
136 syncTimeout: 30 * time.Second,
137 aBlocks: baseChain[:2],
138 bBlocks: baseChain[:10],
143 syncTimeout: 0 * time.Second,
144 aBlocks: baseChain[:50],
145 bBlocks: baseChain[:301],
146 want: baseChain[:50],
147 err: errSkeletonSize,
151 for i, c := range cases {
152 a := mockSync(c.aBlocks, nil, testDBA)
153 b := mockSync(c.bBlocks, nil, testDBB)
154 netWork := NewNetWork()
155 netWork.Register(a, "192.168.0.1", "test node A", consensus.SFFullNode|consensus.SFFastSync)
156 netWork.Register(b, "192.168.0.2", "test node B", consensus.SFFullNode|consensus.SFFastSync)
157 if B2A, A2B, err := netWork.HandsShake(a, b); err != nil {
158 t.Errorf("fail on peer hands shake %v", err)
163 a.blockKeeper.syncPeer = a.peers.GetPeer("test node B")
164 a.blockKeeper.fastSync.setSyncPeer(a.blockKeeper.syncPeer)
166 requireHeadersTimeout = c.syncTimeout
167 if err := a.blockKeeper.fastSync.process(); errors.Root(err) != c.err {
168 t.Errorf("case %d: got %v want %v", i, err, c.err)
171 got := []*types.Block{}
172 for i := uint64(0); i <= a.chain.BestBlockHeight(); i++ {
173 block, err := a.chain.GetBlockByHeight(i)
175 t.Errorf("case %d got err %v", i, err)
177 got = append(got, block)
179 if !testutil.DeepEqual(got, c.want) {
180 t.Errorf("case %d: got %v want %v", i, got, c.want)