OSDN Git Service

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