7 "github.com/vapor/consensus"
8 "github.com/vapor/consensus/difficulty"
9 "github.com/vapor/protocol/bc"
10 "github.com/vapor/protocol/bc/types"
13 func TestCalcPastMedianTime(t *testing.T) {
19 Timestamps: []uint64{1},
23 Timestamps: []uint64{1, 2},
27 Timestamps: []uint64{1, 3, 2},
31 Timestamps: []uint64{1, 3, 2, 3},
35 Timestamps: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 11, 10, 9},
39 Timestamps: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 11, 10, 9, 11, 11, 11, 14},
44 for idx, c := range cases {
45 var parentNode *BlockNode
46 for i, _ := range c.Timestamps {
47 blockHeader := &types.BlockHeader{
49 Timestamp: c.Timestamps[i],
52 blockNode, err := NewBlockNode(blockHeader, parentNode)
56 parentNode = blockNode
59 medianTime := parentNode.CalcPastMedianTime()
60 if medianTime != c.MedianTime {
61 t.Fatalf("calc median timestamp failed, index: %d, expected: %d, have: %d", idx, c.MedianTime, medianTime)
66 func TestCalcNextBits(t *testing.T) {
67 targetTimeSpan := uint64(consensus.BlocksPerRetarget * consensus.TargetSecondsPerBlock)
70 currentNode *BlockNode
74 currentNode: &BlockNode{
81 currentNode: &BlockNode{
82 Height: consensus.BlocksPerRetarget - 1,
88 parentNode: &BlockNode{
92 currentNode: &BlockNode{
93 Height: consensus.BlocksPerRetarget,
94 Bits: difficulty.BigToCompact(big.NewInt(1000)),
95 Timestamp: targetTimeSpan,
97 bits: difficulty.BigToCompact(big.NewInt(1000)),
100 parentNode: &BlockNode{
104 currentNode: &BlockNode{
105 Height: consensus.BlocksPerRetarget,
106 Bits: difficulty.BigToCompact(big.NewInt(1000)),
107 Timestamp: targetTimeSpan * 2,
109 bits: difficulty.BigToCompact(big.NewInt(2000)),
113 for i, c := range cases {
114 c.currentNode.Parent = c.parentNode
115 bits := c.currentNode.CalcNextBits()
117 t.Fatalf("calc next bit failed, index: %d, expected: %d, have: %d", i, c.bits, bits)
122 func TestCalcNextSeed(t *testing.T) {
131 seed: consensus.InitialSeed,
135 Height: consensus.SeedPerRetarget - 1,
136 Seed: &bc.Hash{V1: 100},
138 seed: &bc.Hash{V1: 100},
142 Height: consensus.SeedPerRetarget,
143 Seed: &bc.Hash{V2: 200},
144 Hash: bc.Hash{V3: 300},
146 seed: &bc.Hash{V3: 300},
150 for i, c := range cases {
151 seed := c.node.CalcNextSeed()
152 if *seed != *c.seed {
153 t.Fatalf("calc next seed failed, index: %d, expected: %v, have: %v", i, c.seed, seed)
158 func TestSetMainChain(t *testing.T) {
159 blockIndex := NewBlockIndex()
160 var lastNode *BlockNode
161 for i := uint64(0); i < 4; i++ {
164 Hash: bc.Hash{V0: i},
167 blockIndex.AddNode(node)
172 blockIndex.SetMainChain(lastNode)
173 for lastNode.Parent != nil {
174 if !blockIndex.InMainchain(lastNode.Hash) {
175 t.Fatalf("block %d, hash %v is not in main chain", lastNode.Height, lastNode.Hash)
177 lastNode = lastNode.Parent
180 // fork and set main chain
181 forkHeight := uint64(1)
182 lastNode = blockIndex.nodeByHeight(forkHeight)
183 for i := uint64(1); i <= 3; i++ {
185 Height: lastNode.Height + 1,
186 Hash: bc.Hash{V1: uint64(i)},
189 blockIndex.AddNode(node)
194 blockIndex.SetMainChain(lastNode)
195 for lastNode.Parent != nil {
196 if !blockIndex.InMainchain(lastNode.Hash) {
197 t.Fatalf("after fork, block %d, hash %v is not in main chain", lastNode.Height, lastNode.Hash)
199 lastNode = lastNode.Parent
202 if bestNode != blockIndex.BestNode() {
203 t.Fatalf("check best node failed")
206 for tailNode.Parent != nil && tailNode.Height > forkHeight {
207 if blockIndex.InMainchain(tailNode.Hash) {
208 t.Fatalf("old chain block %d, hash %v still in main chain", tailNode.Height, tailNode.Hash)
210 tailNode = tailNode.Parent