OSDN Git Service

Hulk did something
[bytom/vapor.git] / test / mock / chain.go
1 package mock
2
3 import (
4         "errors"
5         "math/rand"
6
7         "github.com/vapor/protocol/bc"
8         "github.com/vapor/protocol/bc/types"
9 )
10
11 type Chain struct {
12         bestBlockHeader *types.BlockHeader
13         heightMap       map[uint64]*types.Block
14         blockMap        map[bc.Hash]*types.Block
15
16         prevOrphans map[bc.Hash]*types.Block
17 }
18
19 func NewChain() *Chain {
20         return &Chain{
21                 heightMap:   map[uint64]*types.Block{},
22                 blockMap:    map[bc.Hash]*types.Block{},
23                 prevOrphans: make(map[bc.Hash]*types.Block),
24         }
25 }
26
27 func (c *Chain) BestBlockHeader() *types.BlockHeader {
28         return c.bestBlockHeader
29 }
30
31 func (c *Chain) BestBlockHeight() uint64 {
32         return c.bestBlockHeader.Height
33 }
34
35 func (c *Chain) CalcNextSeed(hash *bc.Hash) (*bc.Hash, error) {
36         return &bc.Hash{V0: hash.V1, V1: hash.V2, V2: hash.V3, V3: hash.V0}, nil
37 }
38
39 func (c *Chain) GetBlockByHash(hash *bc.Hash) (*types.Block, error) {
40         block, ok := c.blockMap[*hash]
41         if !ok {
42                 return nil, errors.New("can't find block")
43         }
44         return block, nil
45 }
46
47 func (c *Chain) GetBlockByHeight(height uint64) (*types.Block, error) {
48         block, ok := c.heightMap[height]
49         if !ok {
50                 return nil, errors.New("can't find block")
51         }
52         return block, nil
53 }
54
55 func (c *Chain) GetHeaderByHash(hash *bc.Hash) (*types.BlockHeader, error) {
56         block, ok := c.blockMap[*hash]
57         if !ok {
58                 return nil, errors.New("can't find block")
59         }
60         return &block.BlockHeader, nil
61 }
62
63 func (c *Chain) GetHeaderByHeight(height uint64) (*types.BlockHeader, error) {
64         block, ok := c.heightMap[height]
65         if !ok {
66                 return nil, errors.New("can't find block")
67         }
68         return &block.BlockHeader, nil
69 }
70
71 func (c *Chain) GetTransactionStatus(hash *bc.Hash) (*bc.TransactionStatus, error) {
72         block, err := c.GetBlockByHash(hash)
73         if err != nil {
74                 return nil, errors.New("can't find block by hash")
75         }
76         txCount := len(block.Transactions)
77         var statuses []*bc.TxVerifyResult
78         rand.Seed(int64(block.Height))
79         for i := 0; i < txCount; i++ {
80                 status := &bc.TxVerifyResult{}
81                 if fail := rand.Intn(2); fail == 0 {
82                         status.StatusFail = true
83                 } else {
84                         status.StatusFail = false
85                 }
86                 statuses = append(statuses, status)
87         }
88         txStatus := &bc.TransactionStatus{VerifyStatus: statuses}
89         return txStatus, nil
90 }
91
92 func (c *Chain) InMainChain(hash bc.Hash) bool {
93         block, ok := c.blockMap[hash]
94         if !ok {
95                 return false
96         }
97         return c.heightMap[block.Height] == block
98 }
99
100 func (c *Chain) ProcessBlock(block *types.Block) (bool, error) {
101         if c.bestBlockHeader.Hash() == block.PreviousBlockHash {
102                 c.heightMap[block.Height] = block
103                 c.blockMap[block.Hash()] = block
104                 c.bestBlockHeader = &block.BlockHeader
105                 return false, nil
106         }
107
108         if _, ok := c.blockMap[block.PreviousBlockHash]; !ok {
109                 c.prevOrphans[block.PreviousBlockHash] = block
110                 return true, nil
111         }
112
113         c.blockMap[block.Hash()] = block
114         for c.prevOrphans[block.Hash()] != nil {
115                 block = c.prevOrphans[block.Hash()]
116                 c.blockMap[block.Hash()] = block
117         }
118
119         if block.Height < c.bestBlockHeader.Height {
120                 return false, nil
121         }
122
123         c.bestBlockHeader = &block.BlockHeader
124         for !c.InMainChain(block.Hash()) {
125                 c.heightMap[block.Height] = block
126                 block = c.blockMap[block.PreviousBlockHash]
127         }
128         return false, nil
129 }
130
131 func (c *Chain) SetBestBlockHeader(header *types.BlockHeader) {
132         c.bestBlockHeader = header
133 }
134
135 func (c *Chain) SetBlockByHeight(height uint64, block *types.Block) {
136         c.heightMap[height] = block
137         c.blockMap[block.Hash()] = block
138 }
139
140 func (c *Chain) ValidateTx(*types.Tx) (bool, error) {
141         return false, nil
142 }