OSDN Git Service

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