OSDN Git Service

init delete the pow related (#55)
[bytom/vapor.git] / protocol / state / blockindex_test.go
1 package state
2
3 import (
4         "testing"
5
6         "github.com/davecgh/go-spew/spew"
7
8         "github.com/vapor/protocol/bc"
9         "github.com/vapor/protocol/bc/types"
10 )
11
12 func TestCalcPastMedianTime(t *testing.T) {
13         cases := []struct {
14                 Timestamps []uint64
15                 MedianTime uint64
16         }{
17                 {
18                         Timestamps: []uint64{1},
19                         MedianTime: 1,
20                 },
21                 {
22                         Timestamps: []uint64{1, 2},
23                         MedianTime: 2,
24                 },
25                 {
26                         Timestamps: []uint64{1, 3, 2},
27                         MedianTime: 2,
28                 },
29                 {
30                         Timestamps: []uint64{1, 3, 2, 3},
31                         MedianTime: 3,
32                 },
33                 {
34                         Timestamps: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 11, 10, 9},
35                         MedianTime: 6,
36                 },
37                 {
38                         Timestamps: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 11, 10, 9, 11, 11, 11, 14},
39                         MedianTime: 10,
40                 },
41         }
42
43         for idx, c := range cases {
44                 var parentNode *BlockNode
45                 for i := range c.Timestamps {
46                         blockHeader := &types.BlockHeader{
47                                 Height:    uint64(i),
48                                 Timestamp: c.Timestamps[i],
49                         }
50
51                         blockNode, err := NewBlockNode(blockHeader, parentNode)
52                         if err != nil {
53                                 t.Fatal(err)
54                         }
55                         parentNode = blockNode
56                 }
57
58                 medianTime := parentNode.CalcPastMedianTime()
59                 if medianTime != c.MedianTime {
60                         t.Fatalf("calc median timestamp failed, index: %d, expected: %d, have: %d", idx, c.MedianTime, medianTime)
61                 }
62         }
63 }
64
65 func TestSetMainChain(t *testing.T) {
66         blockIndex := NewBlockIndex()
67         var lastNode *BlockNode
68         for i := uint64(0); i < 4; i++ {
69                 node := &BlockNode{
70                         Height: i,
71                         Hash:   bc.Hash{V0: i},
72                         Parent: lastNode,
73                 }
74                 blockIndex.AddNode(node)
75                 lastNode = node
76         }
77
78         tailNode := lastNode
79         blockIndex.SetMainChain(lastNode)
80         for lastNode.Parent != nil {
81                 if !blockIndex.InMainchain(lastNode.Hash) {
82                         t.Fatalf("block %d, hash %v is not in main chain", lastNode.Height, lastNode.Hash)
83                 }
84                 lastNode = lastNode.Parent
85         }
86
87         // fork and set main chain
88         forkHeight := uint64(1)
89         lastNode = blockIndex.nodeByHeight(forkHeight)
90         for i := uint64(1); i <= 3; i++ {
91                 node := &BlockNode{
92                         Height: lastNode.Height + 1,
93                         Hash:   bc.Hash{V1: uint64(i)},
94                         Parent: lastNode,
95                 }
96                 blockIndex.AddNode(node)
97                 lastNode = node
98         }
99
100         bestNode := lastNode
101         blockIndex.SetMainChain(lastNode)
102         for lastNode.Parent != nil {
103                 if !blockIndex.InMainchain(lastNode.Hash) {
104                         t.Fatalf("after fork, block %d, hash %v is not in main chain", lastNode.Height, lastNode.Hash)
105                 }
106                 lastNode = lastNode.Parent
107         }
108
109         if bestNode != blockIndex.BestNode() {
110                 t.Fatalf("check best node failed")
111         }
112
113         for tailNode.Parent != nil && tailNode.Height > forkHeight {
114                 if blockIndex.InMainchain(tailNode.Hash) {
115                         t.Fatalf("old chain block %d, hash %v still in main chain", tailNode.Height, tailNode.Hash)
116                 }
117                 tailNode = tailNode.Parent
118         }
119 }
120
121 // MockBlockIndex will mock a empty BlockIndex
122 func MockBlockIndex() *BlockIndex {
123         return &BlockIndex{
124                 index:     make(map[bc.Hash]*BlockNode),
125                 mainChain: make([]*BlockNode, 0, 2),
126         }
127 }
128
129 func TestSetMainChainExtendCap(t *testing.T) {
130         blockIndex := MockBlockIndex()
131         var lastNode *BlockNode
132
133         cases := []struct {
134                 start   uint64
135                 stop    uint64
136                 wantLen int
137                 wantCap int
138         }{
139                 {
140                         start:   0,
141                         stop:    500,
142                         wantLen: 500,
143                         wantCap: 500 + approxNodesPerDay,
144                 },
145                 {
146                         start:   500,
147                         stop:    1000,
148                         wantLen: 1000,
149                         wantCap: 500 + approxNodesPerDay,
150                 },
151                 {
152                         start:   1000,
153                         stop:    2000,
154                         wantLen: 2000,
155                         wantCap: 2000 + approxNodesPerDay,
156                 },
157         }
158
159         for num, c := range cases {
160                 for i := c.start; i < c.stop; i++ {
161                         node := &BlockNode{
162                                 Height: i,
163                                 Hash:   bc.Hash{V0: i},
164                                 Parent: lastNode,
165                         }
166                         blockIndex.AddNode(node)
167                         lastNode = node
168                 }
169                 blockIndex.SetMainChain(lastNode)
170                 if c.wantLen != len(blockIndex.mainChain) || c.wantCap != cap(blockIndex.mainChain) {
171                         t.Fatalf("SetMainChain extended capacity error, index: %d, got len: %d, got cap: %d, want len: %d, want cap: %d", num, len(blockIndex.mainChain), cap(blockIndex.mainChain), c.wantLen, c.wantCap)
172                 }
173         }
174
175         for i := 0; i < len(blockIndex.mainChain); i++ {
176                 if blockIndex.mainChain[i] != blockIndex.index[blockIndex.mainChain[i].Hash] {
177                         t.Fatal("SetMainChain extended capacity error, index:", i, "want:", spew.Sdump(blockIndex.mainChain[i]), "got:", spew.Sdump(blockIndex.index[blockIndex.mainChain[i].Hash]))
178                 }
179         }
180 }