OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / netsync / tool_test.go
1 package netsync
2
3 import (
4         "errors"
5         "math/rand"
6         "net"
7         "time"
8
9         wire "github.com/tendermint/go-wire"
10         "github.com/tendermint/tmlibs/flowrate"
11
12         "github.com/vapor/consensus"
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 *SyncManager
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) ServiceFlag() consensus.ServiceFlag {
48         return p.flag
49 }
50
51 func (p *P2PPeer) SetConnection(srcPeer *P2PPeer, node *SyncManager) {
52         p.srcPeer = srcPeer
53         p.remoteNode = node
54 }
55
56 func (p *P2PPeer) TrafficStatus() (*flowrate.Status, *flowrate.Status) {
57         return nil, nil
58 }
59
60 func (p *P2PPeer) TrySend(b byte, msg interface{}) bool {
61         msgBytes := wire.BinaryBytes(msg)
62         if p.async {
63                 p.msgCh <- msgBytes
64         } else {
65                 msgType, msg, _ := DecodeMessage(msgBytes)
66                 p.remoteNode.processMsg(p.srcPeer, msgType, msg)
67         }
68         return true
69 }
70
71 func (p *P2PPeer) setAsync(b bool) {
72         p.async = b
73 }
74
75 func (p *P2PPeer) postMan() {
76         for msgBytes := range p.msgCh {
77                 msgType, msg, _ := DecodeMessage(msgBytes)
78                 p.remoteNode.processMsg(p.srcPeer, msgType, msg)
79         }
80 }
81
82 type PeerSet struct{}
83
84 func NewPeerSet() *PeerSet {
85         return &PeerSet{}
86 }
87
88 func (ps *PeerSet) AddBannedPeer(string) error { return nil }
89 func (ps *PeerSet) StopPeerGracefully(string)  {}
90
91 type NetWork struct {
92         nodes map[*SyncManager]P2PPeer
93 }
94
95 func NewNetWork() *NetWork {
96         return &NetWork{map[*SyncManager]P2PPeer{}}
97 }
98
99 func (nw *NetWork) Register(node *SyncManager, addr, id string, flag consensus.ServiceFlag) {
100         peer := NewP2PPeer(addr, id, flag)
101         nw.nodes[node] = *peer
102 }
103
104 func (nw *NetWork) HandsShake(nodeA, nodeB *SyncManager) (*P2PPeer, *P2PPeer, error) {
105         B2A, ok := nw.nodes[nodeA]
106         if !ok {
107                 return nil, nil, errors.New("can't find nodeA's p2p peer on network")
108         }
109         A2B, ok := nw.nodes[nodeB]
110         if !ok {
111                 return nil, nil, errors.New("can't find nodeB's p2p peer on network")
112         }
113
114         A2B.SetConnection(&B2A, nodeB)
115         B2A.SetConnection(&A2B, nodeA)
116
117         nodeA.handleStatusRequestMsg(&A2B)
118         nodeB.handleStatusRequestMsg(&B2A)
119
120         A2B.setAsync(true)
121         B2A.setAsync(true)
122         return &B2A, &A2B, nil
123 }
124
125 func mockBlocks(startBlock *types.Block, height uint64) []*types.Block {
126         blocks := []*types.Block{}
127         indexBlock := &types.Block{}
128         if startBlock == nil {
129                 indexBlock = &types.Block{BlockHeader: types.BlockHeader{}}
130                 blocks = append(blocks, indexBlock)
131         } else {
132                 indexBlock = startBlock
133         }
134
135         for indexBlock.Height < height {
136                 block := &types.Block{
137                         BlockHeader: types.BlockHeader{
138                                 Height:            indexBlock.Height + 1,
139                                 PreviousBlockHash: indexBlock.Hash(),
140                         },
141                 }
142                 blocks = append(blocks, block)
143                 indexBlock = block
144         }
145         return blocks
146 }
147
148 func mockSync(blocks []*types.Block) *SyncManager {
149         chain := mock.NewChain()
150         peers := newPeerSet(NewPeerSet())
151         chain.SetBestBlockHeader(&blocks[len(blocks)-1].BlockHeader)
152         for _, block := range blocks {
153                 chain.SetBlockByHeight(block.Height, block)
154         }
155
156         genesis, _ := chain.GetHeaderByHeight(0)
157         return &SyncManager{
158                 genesisHash: genesis.Hash(),
159                 chain:       chain,
160                 blockKeeper: newBlockKeeper(chain, peers),
161                 peers:       peers,
162         }
163 }
164
165 func mockTxs(txCount int) ([]*types.Tx, []*bc.Tx) {
166         var txs []*types.Tx
167         var bcTxs []*bc.Tx
168         for i := 0; i < txCount; i++ {
169                 trueProg := mockControlProgram(60)
170                 assetID := bc.ComputeAssetID(trueProg, 1, &bc.EmptyStringHash)
171                 now := []byte(time.Now().String())
172                 issuanceInp := types.NewIssuanceInput(now, 1, trueProg, nil, nil)
173                 tx := types.NewTx(types.TxData{
174                         Version: 1,
175                         Inputs:  []*types.TxInput{issuanceInp},
176                         Outputs: []*types.TxOutput{types.NewTxOutput(assetID, 1, trueProg)},
177                 })
178                 txs = append(txs, tx)
179                 bcTxs = append(bcTxs, tx.Tx)
180         }
181         return txs, bcTxs
182 }
183
184 func mockControlProgram(length int) []byte {
185         var cp []byte
186         for i := 0; i < length; i++ {
187                 cp = append(cp, byte(rand.Intn(1<<8)))
188         }
189         return cp
190 }