OSDN Git Service

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