OSDN Git Service

netsync add test case (#365)
[bytom/vapor.git] / netsync / chainmgr / tool_test.go
1 package chainmgr
2
3 import (
4         "errors"
5         "math/rand"
6         "net"
7         "time"
8
9         "github.com/tendermint/go-wire"
10         "github.com/tendermint/tmlibs/flowrate"
11         dbm "github.com/vapor/database/leveldb"
12
13         "github.com/vapor/consensus"
14         "github.com/vapor/netsync/peers"
15         "github.com/vapor/protocol/bc"
16         "github.com/vapor/protocol/bc/types"
17         "github.com/vapor/test/mock"
18 )
19
20 type P2PPeer struct {
21         id   string
22         ip   *net.IPAddr
23         flag consensus.ServiceFlag
24
25         srcPeer    *P2PPeer
26         remoteNode *Manager
27         msgCh      chan []byte
28         async      bool
29 }
30
31 func NewP2PPeer(addr, id string, flag consensus.ServiceFlag) *P2PPeer {
32         return &P2PPeer{
33                 id:    id,
34                 ip:    &net.IPAddr{IP: net.ParseIP(addr)},
35                 flag:  flag,
36                 msgCh: make(chan []byte),
37                 async: false,
38         }
39 }
40
41 func (p *P2PPeer) Addr() net.Addr {
42         return p.ip
43 }
44
45 func (p *P2PPeer) ID() string {
46         return p.id
47 }
48
49 func (p *P2PPeer) IsLAN() bool {
50         return false
51 }
52
53 func (p *P2PPeer) RemoteAddrHost() string {
54         return ""
55 }
56
57 func (p *P2PPeer) ServiceFlag() consensus.ServiceFlag {
58         return p.flag
59 }
60
61 func (p *P2PPeer) SetConnection(srcPeer *P2PPeer, node *Manager) {
62         p.srcPeer = srcPeer
63         p.remoteNode = node
64 }
65
66 func (p *P2PPeer) TrafficStatus() (*flowrate.Status, *flowrate.Status) {
67         return nil, nil
68 }
69
70 func (p *P2PPeer) TrySend(b byte, msg interface{}) bool {
71         msgBytes := wire.BinaryBytes(msg)
72         if p.async {
73                 p.msgCh <- msgBytes
74         } else {
75                 msgType, msg, _ := decodeMessage(msgBytes)
76                 p.remoteNode.processMsg(p.srcPeer, msgType, msg)
77         }
78         return true
79 }
80
81 func (p *P2PPeer) setAsync(b bool) {
82         p.async = b
83 }
84
85 func (p *P2PPeer) postMan() {
86         for msgBytes := range p.msgCh {
87                 msgType, msg, _ := decodeMessage(msgBytes)
88                 time.Sleep(10 * time.Millisecond)
89                 p.remoteNode.processMsg(p.srcPeer, msgType, msg)
90         }
91 }
92
93 type PeerSet struct{}
94
95 func NewPeerSet() *PeerSet {
96         return &PeerSet{}
97 }
98
99 func (ps *PeerSet) IsBanned(ip string, level byte, reason string) bool {
100         return false
101 }
102
103 func (ps *PeerSet) StopPeerGracefully(string) {}
104
105 type NetWork struct {
106         nodes map[*Manager]P2PPeer
107 }
108
109 func NewNetWork() *NetWork {
110         return &NetWork{map[*Manager]P2PPeer{}}
111 }
112
113 func (nw *NetWork) Register(node *Manager, addr, id string, flag consensus.ServiceFlag) {
114         peer := NewP2PPeer(addr, id, flag)
115         nw.nodes[node] = *peer
116 }
117
118 func (nw *NetWork) HandsShake(nodeA, nodeB *Manager) (*P2PPeer, *P2PPeer, error) {
119         B2A, ok := nw.nodes[nodeA]
120         if !ok {
121                 return nil, nil, errors.New("can't find nodeA's p2p peer on network")
122         }
123         A2B, ok := nw.nodes[nodeB]
124         if !ok {
125                 return nil, nil, errors.New("can't find nodeB's p2p peer on network")
126         }
127
128         A2B.SetConnection(&B2A, nodeB)
129         B2A.SetConnection(&A2B, nodeA)
130
131         nodeA.AddPeer(&A2B)
132         nodeB.AddPeer(&B2A)
133         nodeA.SendStatus(B2A.srcPeer)
134         nodeB.SendStatus(A2B.srcPeer)
135         A2B.setAsync(true)
136         B2A.setAsync(true)
137         return &B2A, &A2B, nil
138 }
139
140 func mockBlocks(startBlock *types.Block, height uint64) []*types.Block {
141         blocks := []*types.Block{}
142         indexBlock := &types.Block{}
143         if startBlock == nil {
144                 indexBlock = &types.Block{BlockHeader: types.BlockHeader{Version: uint64(rand.Uint32())}}
145                 blocks = append(blocks, indexBlock)
146         } else {
147                 indexBlock = startBlock
148         }
149
150         for indexBlock.Height < height {
151                 block := &types.Block{
152                         BlockHeader: types.BlockHeader{
153                                 Height:            indexBlock.Height + 1,
154                                 PreviousBlockHash: indexBlock.Hash(),
155                                 Version:           uint64(rand.Uint32()),
156                         },
157                 }
158                 blocks = append(blocks, block)
159                 indexBlock = block
160         }
161         return blocks
162 }
163
164 func mockErrorBlocks(startBlock *types.Block, height uint64, errBlockHeight uint64) []*types.Block {
165         blocks := []*types.Block{}
166         indexBlock := &types.Block{}
167         if startBlock == nil {
168                 indexBlock = &types.Block{BlockHeader: types.BlockHeader{Version: uint64(rand.Uint32())}}
169                 blocks = append(blocks, indexBlock)
170         } else {
171                 indexBlock = startBlock
172         }
173
174         for indexBlock.Height < height {
175                 block := &types.Block{
176                         BlockHeader: types.BlockHeader{
177                                 Height:            indexBlock.Height + 1,
178                                 PreviousBlockHash: indexBlock.Hash(),
179                                 Version:           uint64(rand.Uint32()),
180                         },
181                 }
182                 if block.Height == errBlockHeight {
183                         block.TransactionsMerkleRoot = bc.NewHash([32]byte{0x1})
184                 }
185                 blocks = append(blocks, block)
186                 indexBlock = block
187         }
188         return blocks
189 }
190
191 func mockSync(blocks []*types.Block, mempool *mock.Mempool, fastSyncDB dbm.DB) *Manager {
192         chain := mock.NewChain(mempool)
193         peers := peers.NewPeerSet(NewPeerSet())
194         chain.SetBestBlockHeader(&blocks[len(blocks)-1].BlockHeader)
195         for _, block := range blocks {
196                 chain.SetBlockByHeight(block.Height, block)
197         }
198
199         return &Manager{
200                 chain:       chain,
201                 blockKeeper: newBlockKeeper(chain, peers, fastSyncDB),
202                 peers:       peers,
203                 mempool:     mempool,
204                 txSyncCh:    make(chan *txSyncMsg),
205         }
206 }
207
208 func mockTxs(txCount int) ([]*types.Tx, []*bc.Tx) {
209         var txs []*types.Tx
210         var bcTxs []*bc.Tx
211         trueProg := mockControlProgram(60)
212         assetID := bc.AssetID{V0: 9999}
213         for i := uint64(0); i < uint64(txCount); i++ {
214                 tx := types.NewTx(types.TxData{
215                         Version: 1,
216                         Inputs:  []*types.TxInput{types.NewSpendInput(nil, bc.Hash{V0: i + 1}, assetID, i, i, trueProg)},
217                         Outputs: []*types.TxOutput{types.NewIntraChainOutput(assetID, 1, trueProg)},
218                 })
219                 txs = append(txs, tx)
220                 bcTxs = append(bcTxs, tx.Tx)
221         }
222         return txs, bcTxs
223 }
224
225 func mockControlProgram(length int) []byte {
226         var cp []byte
227         for i := 0; i < length; i++ {
228                 cp = append(cp, byte(rand.Intn(1<<8)))
229         }
230         return cp
231 }