OSDN Git Service

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