OSDN Git Service

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