github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/p2p/switch_test.go (about) 1 package p2p 2 3 import ( 4 "io/ioutil" 5 "os" 6 "sync" 7 "testing" 8 "time" 9 10 "github.com/davecgh/go-spew/spew" 11 "github.com/tendermint/go-crypto" 12 13 cfg "github.com/bytom/bytom/config" 14 dbm "github.com/bytom/bytom/database/leveldb" 15 "github.com/bytom/bytom/errors" 16 conn "github.com/bytom/bytom/p2p/connection" 17 "github.com/bytom/bytom/p2p/security" 18 ) 19 20 var ( 21 testCfg *cfg.Config 22 ) 23 24 func init() { 25 testCfg = cfg.DefaultConfig() 26 } 27 28 /* 29 Each peer has one `MConnection` (multiplex connection) instance. 30 31 __multiplex__ *noun* a system or signal involving simultaneous transmission of 32 several messages along a single channel of communication. 33 34 Each `MConnection` handles message transmission on multiple abstract communication 35 `Channel`s. Each channel has a globally unique byte id. 36 The byte id and the relative priorities of each `Channel` are configured upon 37 initialization of the connection. 38 39 There are two methods for sending messages: 40 func (m MConnection) Send(chID byte, msgBytes []byte) bool {} 41 func (m MConnection) TrySend(chID byte, msgBytes []byte}) bool {} 42 43 `Send(chID, msgBytes)` is a blocking call that waits until `msg` is 44 successfully queued for the channel with the given id byte `chID`, or until the 45 request times out. The message `msg` is serialized using Go-Amino. 46 47 `TrySend(chID, msgBytes)` is a nonblocking call that returns false if the 48 channel's queue is full. 49 50 Inbound message bytes are handled with an onReceive callback function. 51 */ 52 type PeerMessage struct { 53 PeerID string 54 Bytes []byte 55 Counter int 56 } 57 58 type TestReactor struct { 59 BaseReactor 60 61 mtx sync.Mutex 62 channels []*conn.ChannelDescriptor 63 logMessages bool 64 msgsCounter int 65 msgsReceived map[byte][]PeerMessage 66 } 67 68 func NewTestReactor(channels []*conn.ChannelDescriptor, logMessages bool) *TestReactor { 69 tr := &TestReactor{ 70 channels: channels, 71 logMessages: logMessages, 72 msgsReceived: make(map[byte][]PeerMessage), 73 } 74 tr.BaseReactor = *NewBaseReactor("TestReactor", tr) 75 76 return tr 77 } 78 79 // GetChannels implements Reactor 80 func (tr *TestReactor) GetChannels() []*conn.ChannelDescriptor { 81 return tr.channels 82 } 83 84 // OnStart implements BaseService 85 func (tr *TestReactor) OnStart() error { 86 tr.BaseReactor.OnStart() 87 return nil 88 } 89 90 // OnStop implements BaseService 91 func (tr *TestReactor) OnStop() { 92 tr.BaseReactor.OnStop() 93 } 94 95 // AddPeer implements Reactor by sending our state to peer. 96 func (tr *TestReactor) AddPeer(peer *Peer) error { 97 return nil 98 } 99 100 // RemovePeer implements Reactor by removing peer from the pool. 101 func (tr *TestReactor) RemovePeer(peer *Peer, reason interface{}) { 102 } 103 104 // Receive implements Reactor by handling 4 types of messages (look below). 105 func (tr *TestReactor) Receive(chID byte, peer *Peer, msgBytes []byte) { 106 if tr.logMessages { 107 tr.mtx.Lock() 108 defer tr.mtx.Unlock() 109 tr.msgsReceived[chID] = append(tr.msgsReceived[chID], PeerMessage{peer.ID(), msgBytes, tr.msgsCounter}) 110 tr.msgsCounter++ 111 } 112 } 113 114 func initSwitchFunc(sw *Switch) *Switch { 115 // Make two reactors of two channels each 116 sw.AddReactor("foo", NewTestReactor([]*conn.ChannelDescriptor{ 117 {ID: byte(0x00), Priority: 10}, 118 {ID: byte(0x01), Priority: 10}, 119 }, true)) 120 sw.AddReactor("bar", NewTestReactor([]*conn.ChannelDescriptor{ 121 {ID: byte(0x02), Priority: 10}, 122 {ID: byte(0x03), Priority: 10}, 123 }, true)) 124 125 return sw 126 } 127 128 //Test connect self. 129 func TestFiltersOutItself(t *testing.T) { 130 t.Skip("due to fail on mac") 131 dirPath, err := ioutil.TempDir(".", "") 132 if err != nil { 133 t.Fatal(err) 134 } 135 defer os.RemoveAll(dirPath) 136 137 testDB := dbm.NewDB("testdb", "leveldb", dirPath) 138 cfg := *testCfg 139 cfg.DBPath = dirPath 140 cfg.P2P.ListenAddress = "127.0.1.1:0" 141 swPrivKey := crypto.GenPrivKeyEd25519() 142 cfg.P2P.PrivateKey = swPrivKey.String() 143 s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) 144 s1.Start() 145 defer s1.Stop() 146 147 rmdirPath, err := ioutil.TempDir(".", "") 148 if err != nil { 149 t.Fatal(err) 150 } 151 defer os.RemoveAll(rmdirPath) 152 153 // simulate s1 having a public key and creating a remote peer with the same key 154 rpCfg := *testCfg 155 rpCfg.DBPath = rmdirPath 156 rp := &remotePeer{PrivKey: s1.nodePrivKey, Config: &rpCfg} 157 rp.Start() 158 defer rp.Stop() 159 if err = s1.DialPeerWithAddress(rp.addr); errors.Root(err) != ErrConnectSelf { 160 t.Fatal(err) 161 } 162 163 //S1 dialing itself ip address 164 addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr()) 165 166 if err := s1.DialPeerWithAddress(addr); errors.Root(err) != ErrConnectSelf { 167 t.Fatal(err) 168 } 169 } 170 171 func TestDialBannedPeer(t *testing.T) { 172 t.Skip("due to fail on mac") 173 dirPath, err := ioutil.TempDir(".", "") 174 if err != nil { 175 t.Fatal(err) 176 } 177 defer os.RemoveAll(dirPath) 178 179 testDB := dbm.NewDB("testdb", "leveldb", dirPath) 180 cfg := *testCfg 181 cfg.DBPath = dirPath 182 cfg.P2P.ListenAddress = "127.0.1.1:0" 183 swPrivKey := crypto.GenPrivKeyEd25519() 184 cfg.P2P.PrivateKey = swPrivKey.String() 185 s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) 186 s1.Start() 187 defer s1.Stop() 188 189 rmdirPath, err := ioutil.TempDir(".", "") 190 if err != nil { 191 t.Fatal(err) 192 } 193 defer os.RemoveAll(rmdirPath) 194 195 rpCfg := *testCfg 196 rpCfg.DBPath = rmdirPath 197 rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: &rpCfg} 198 rp.Start() 199 defer rp.Stop() 200 for { 201 if ok := s1.security.IsBanned(rp.addr.IP.String(), security.LevelMsgIllegal, "test"); ok { 202 break 203 } 204 } 205 if err := s1.DialPeerWithAddress(rp.addr); errors.Root(err) != security.ErrConnectBannedPeer { 206 t.Fatal(err) 207 } 208 } 209 210 func TestDuplicateOutBoundPeer(t *testing.T) { 211 t.Skip("due to fail on mac") 212 dirPath, err := ioutil.TempDir(".", "") 213 if err != nil { 214 t.Fatal(err) 215 } 216 defer os.RemoveAll(dirPath) 217 218 testDB := dbm.NewDB("testdb", "leveldb", dirPath) 219 cfg := *testCfg 220 cfg.DBPath = dirPath 221 cfg.P2P.ListenAddress = "127.0.1.1:0" 222 swPrivKey := crypto.GenPrivKeyEd25519() 223 cfg.P2P.PrivateKey = swPrivKey.String() 224 s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) 225 s1.Start() 226 defer s1.Stop() 227 228 rmdirPath, err := ioutil.TempDir(".", "") 229 if err != nil { 230 t.Fatal(err) 231 } 232 defer os.RemoveAll(rmdirPath) 233 234 rpCfg := *testCfg 235 rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: &rpCfg} 236 rp.Start() 237 defer rp.Stop() 238 239 if err = s1.DialPeerWithAddress(rp.addr); err != nil { 240 t.Fatal(err) 241 } 242 243 if err = s1.DialPeerWithAddress(rp.addr); errors.Root(err) != ErrDuplicatePeer { 244 t.Fatal(err) 245 } 246 } 247 248 func TestDuplicateInBoundPeer(t *testing.T) { 249 t.Skip("due to fail on mac") 250 dirPath, err := ioutil.TempDir(".", "") 251 if err != nil { 252 t.Fatal(err) 253 } 254 defer os.RemoveAll(dirPath) 255 256 testDB := dbm.NewDB("testdb", "leveldb", dirPath) 257 cfg := *testCfg 258 cfg.DBPath = dirPath 259 cfg.P2P.ListenAddress = "127.0.1.1:0" 260 swPrivKey := crypto.GenPrivKeyEd25519() 261 cfg.P2P.PrivateKey = swPrivKey.String() 262 s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) 263 s1.Start() 264 defer s1.Stop() 265 266 inpCfg := *testCfg 267 inp := &inboundPeer{PrivKey: crypto.GenPrivKeyEd25519(), config: &inpCfg} 268 addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr()) 269 if err != nil { 270 t.Fatal(err) 271 } 272 go inp.dial(addr) 273 274 inp1Cfg := *testCfg 275 inp1 := &inboundPeer{PrivKey: inp.PrivKey, config: &inp1Cfg} 276 go inp1.dial(addr) 277 278 time.Sleep(1 * time.Second) 279 if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 1 { 280 t.Fatal("TestDuplicateInBoundPeer peer size error want 1, got:", outbound, inbound, dialing, spew.Sdump(s1.peers.lookup)) 281 } 282 } 283 284 func TestAddInboundPeer(t *testing.T) { 285 t.Skip("due to fail on mac") 286 dirPath, err := ioutil.TempDir(".", "") 287 if err != nil { 288 t.Fatal(err) 289 } 290 defer os.RemoveAll(dirPath) 291 292 testDB := dbm.NewDB("testdb", "leveldb", dirPath) 293 cfg := *testCfg 294 cfg.DBPath = dirPath 295 cfg.P2P.MaxNumPeers = 2 296 cfg.P2P.ListenAddress = "127.0.1.1:0" 297 swPrivKey := crypto.GenPrivKeyEd25519() 298 cfg.P2P.PrivateKey = swPrivKey.String() 299 s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) 300 s1.Start() 301 defer s1.Stop() 302 303 inpCfg := *testCfg 304 inpPrivKey := crypto.GenPrivKeyEd25519() 305 inpCfg.P2P.PrivateKey = inpPrivKey.String() 306 inp := &inboundPeer{PrivKey: inpPrivKey, config: &inpCfg} 307 addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr()) 308 if err != nil { 309 t.Fatal(err) 310 } 311 go inp.dial(addr) 312 313 rpCfg := *testCfg 314 rpPrivKey := crypto.GenPrivKeyEd25519() 315 rpCfg.P2P.PrivateKey = rpPrivKey.String() 316 rp := &remotePeer{PrivKey: rpPrivKey, Config: &rpCfg} 317 rp.Start() 318 defer rp.Stop() 319 320 if err := s1.DialPeerWithAddress(rp.addr); err != nil { 321 t.Fatal(err) 322 } 323 324 inp2Cfg := *testCfg 325 inp2PrivKey := crypto.GenPrivKeyEd25519() 326 inp2Cfg.P2P.PrivateKey = inp2PrivKey.String() 327 inp2 := &inboundPeer{PrivKey: inp2PrivKey, config: &inp2Cfg} 328 329 go inp2.dial(addr) 330 331 time.Sleep(1 * time.Second) 332 if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 2 { 333 t.Fatal("TestAddInboundPeer peer size error want 2 got:", spew.Sdump(s1.peers.lookup)) 334 } 335 } 336 337 func TestStopPeer(t *testing.T) { 338 t.Skip("due to fail on mac") 339 dirPath, err := ioutil.TempDir(".", "") 340 if err != nil { 341 t.Fatal(err) 342 } 343 defer os.RemoveAll(dirPath) 344 345 testDB := dbm.NewDB("testdb", "leveldb", dirPath) 346 cfg := *testCfg 347 cfg.DBPath = dirPath 348 cfg.P2P.MaxNumPeers = 2 349 cfg.P2P.ListenAddress = "127.0.1.1:0" 350 swPrivKey := crypto.GenPrivKeyEd25519() 351 cfg.P2P.PrivateKey = swPrivKey.String() 352 s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc) 353 s1.Start() 354 defer s1.Stop() 355 356 inpCfg := *testCfg 357 inpPrivKey := crypto.GenPrivKeyEd25519() 358 inpCfg.P2P.PrivateKey = inpPrivKey.String() 359 inp := &inboundPeer{PrivKey: inpPrivKey, config: &inpCfg} 360 addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr()) 361 if err != nil { 362 t.Fatal(err) 363 } 364 go inp.dial(addr) 365 366 rpCfg := *testCfg 367 rpPrivKey := crypto.GenPrivKeyEd25519() 368 rpCfg.P2P.PrivateKey = rpPrivKey.String() 369 rp := &remotePeer{PrivKey: rpPrivKey, Config: &rpCfg} 370 rp.Start() 371 defer rp.Stop() 372 373 if err := s1.DialPeerWithAddress(rp.addr); err != nil { 374 t.Fatal(err) 375 } 376 time.Sleep(1 * time.Second) 377 if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 2 { 378 t.Fatal("TestStopPeer peer size error want 2,got:", spew.Sdump(s1.peers.lookup)) 379 } 380 381 s1.StopPeerGracefully(s1.peers.list[0].Key) 382 if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 1 { 383 t.Fatal("TestStopPeer peer size error,want 1,got:", spew.Sdump(s1.peers.lookup)) 384 } 385 386 s1.StopPeerForError(s1.peers.list[0], "stop for test") 387 if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 0 { 388 t.Fatal("TestStopPeer peer size error,want 0, got:", spew.Sdump(s1.peers.lookup)) 389 } 390 }