OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / p2p / test_util.go
1 package p2p
2
3 import (
4         "math/rand"
5         "net"
6
7         "github.com/tendermint/go-crypto"
8         cmn "github.com/tendermint/tmlibs/common"
9
10         cfg "github.com/vapor/config"
11         "github.com/vapor/p2p/connection"
12 )
13
14 //PanicOnAddPeerErr add peer error
15 var PanicOnAddPeerErr = false
16
17 func CreateRandomPeer(outbound bool) *Peer {
18         _, netAddr := CreateRoutableAddr()
19         p := &Peer{
20                 peerConn: &peerConn{
21                         outbound: outbound,
22                 },
23                 NodeInfo: &NodeInfo{
24                         ListenAddr: netAddr.DialString(),
25                 },
26                 mconn: &connection.MConnection{},
27         }
28         return p
29 }
30
31 func CreateRoutableAddr() (addr string, netAddr *NetAddress) {
32         for {
33                 var err error
34                 addr = cmn.Fmt("%X@%v.%v.%v.%v:46656", cmn.RandBytes(20), cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256)
35                 netAddr, err = NewNetAddressString(addr)
36                 if err != nil {
37                         panic(err)
38                 }
39                 if netAddr.Routable() {
40                         break
41                 }
42         }
43         return
44 }
45
46 // MakeConnectedSwitches switches connected via arbitrary net.Conn; useful for testing
47 // Returns n switches, connected according to the connect func.
48 // If connect==Connect2Switches, the switches will be fully connected.
49 // initSwitch defines how the ith switch should be initialized (ie. with what reactors).
50 // NOTE: panics if any switch fails to start.
51 func MakeConnectedSwitches(cfg *cfg.Config, n int, initSwitch func(int, *Switch) *Switch, connect func([]*Switch, int, int)) []*Switch {
52         switches := make([]*Switch, n)
53         for i := 0; i < n; i++ {
54                 switches[i] = MakeSwitch(cfg, i, "testing", "123.123.123", initSwitch)
55         }
56
57         if err := startSwitches(switches); err != nil {
58                 panic(err)
59         }
60
61         for i := 0; i < n; i++ {
62                 for j := i; j < n; j++ {
63                         connect(switches, i, j)
64                 }
65         }
66
67         return switches
68 }
69
70 // Connect2Switches will connect switches i and j via net.Pipe()
71 // Blocks until a conection is established.
72 // NOTE: caller ensures i and j are within bounds
73 func Connect2Switches(switches []*Switch, i, j int) {
74         switchI := switches[i]
75         switchJ := switches[j]
76         c1, c2 := net.Pipe()
77         doneCh := make(chan struct{})
78         go func() {
79                 err := switchI.addPeerWithConnection(c1)
80                 if PanicOnAddPeerErr && err != nil {
81                         panic(err)
82                 }
83                 doneCh <- struct{}{}
84         }()
85         go func() {
86                 err := switchJ.addPeerWithConnection(c2)
87                 if PanicOnAddPeerErr && err != nil {
88                         panic(err)
89                 }
90                 doneCh <- struct{}{}
91         }()
92         <-doneCh
93         <-doneCh
94 }
95
96 func startSwitches(switches []*Switch) error {
97         for _, s := range switches {
98                 _, err := s.Start() // start switch and reactors
99                 if err != nil {
100                         return err
101                 }
102         }
103         return nil
104 }
105
106 func MakeSwitch(cfg *cfg.Config, i int, network, version string, initSwitch func(int, *Switch) *Switch) *Switch {
107         privKey := crypto.GenPrivKeyEd25519()
108         // new switch, add reactors
109         // TODO: let the config be passed in?
110         s := initSwitch(i, NewSwitch(cfg))
111         s.SetNodeInfo(&NodeInfo{
112                 PubKey:     privKey.PubKey().Unwrap().(crypto.PubKeyEd25519),
113                 Moniker:    cmn.Fmt("switch%d", i),
114                 Network:    network,
115                 Version:    version,
116                 ListenAddr: cmn.Fmt("%v:%v", network, rand.Intn(64512)+1023),
117         })
118         s.SetNodePrivKey(privKey)
119         return s
120 }