6 "github.com/davecgh/go-spew/spew"
8 "github.com/vapor/protocol/bc"
9 "github.com/vapor/protocol/bc/types"
12 func TestCalcPastMedianTime(t *testing.T) {
18 Timestamps: []uint64{1},
22 Timestamps: []uint64{1, 2},
26 Timestamps: []uint64{1, 3, 2},
30 Timestamps: []uint64{1, 3, 2, 3},
34 Timestamps: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 11, 10, 9},
38 Timestamps: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 11, 10, 9, 11, 11, 11, 14},
43 for idx, c := range cases {
44 var parentNode *BlockNode
45 for i := range c.Timestamps {
46 blockHeader := &types.BlockHeader{
48 Timestamp: c.Timestamps[i],
51 blockNode, err := NewBlockNode(blockHeader, parentNode)
55 parentNode = blockNode
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)
65 func TestSetMainChain(t *testing.T) {
66 blockIndex := NewBlockIndex()
67 var lastNode *BlockNode
68 for i := uint64(0); i < 4; i++ {
74 blockIndex.AddNode(node)
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)
84 lastNode = lastNode.Parent
87 // fork and set main chain
88 forkHeight := uint64(1)
89 lastNode = blockIndex.nodeByHeight(forkHeight)
90 for i := uint64(1); i <= 3; i++ {
92 Height: lastNode.Height + 1,
93 Hash: bc.Hash{V1: uint64(i)},
96 blockIndex.AddNode(node)
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)
106 lastNode = lastNode.Parent
109 if bestNode != blockIndex.BestNode() {
110 t.Fatalf("check best node failed")
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)
117 tailNode = tailNode.Parent
121 // MockBlockIndex will mock a empty BlockIndex
122 func MockBlockIndex() *BlockIndex {
124 index: make(map[bc.Hash]*BlockNode),
125 heightIndex: make(map[uint64][]*BlockNode),
126 mainChain: make([]*BlockNode, 0, 2),
130 func TestSetMainChainExtendCap(t *testing.T) {
131 blockIndex := MockBlockIndex()
132 var lastNode *BlockNode
144 wantCap: 500 + approxNodesPerDay,
150 wantCap: 500 + approxNodesPerDay,
156 wantCap: 2000 + approxNodesPerDay,
160 for num, c := range cases {
161 for i := c.start; i < c.stop; i++ {
164 Hash: bc.Hash{V0: i},
167 blockIndex.AddNode(node)
170 blockIndex.SetMainChain(lastNode)
171 if c.wantLen != len(blockIndex.mainChain) || c.wantCap != cap(blockIndex.mainChain) {
172 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)
176 for i := 0; i < len(blockIndex.mainChain); i++ {
177 if blockIndex.mainChain[i] != blockIndex.index[blockIndex.mainChain[i].Hash] {
178 t.Fatal("SetMainChain extended capacity error, index:", i, "want:", spew.Sdump(blockIndex.mainChain[i]), "got:", spew.Sdump(blockIndex.index[blockIndex.mainChain[i].Hash]))