github.com/MaynardMiner/ethereumprogpow@v1.8.23/p2p/server_test.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package p2p 18 19 import ( 20 "crypto/ecdsa" 21 "errors" 22 "math/rand" 23 "net" 24 "reflect" 25 "testing" 26 "time" 27 28 "github.com/ethereumprogpow/ethereumprogpow/crypto" 29 "github.com/ethereumprogpow/ethereumprogpow/log" 30 "github.com/ethereumprogpow/ethereumprogpow/p2p/enode" 31 "github.com/ethereumprogpow/ethereumprogpow/p2p/enr" 32 "golang.org/x/crypto/sha3" 33 ) 34 35 // func init() { 36 // log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(false)))) 37 // } 38 39 type testTransport struct { 40 rpub *ecdsa.PublicKey 41 *rlpx 42 43 closeErr error 44 } 45 46 func newTestTransport(rpub *ecdsa.PublicKey, fd net.Conn) transport { 47 wrapped := newRLPX(fd).(*rlpx) 48 wrapped.rw = newRLPXFrameRW(fd, secrets{ 49 MAC: zero16, 50 AES: zero16, 51 IngressMAC: sha3.NewLegacyKeccak256(), 52 EgressMAC: sha3.NewLegacyKeccak256(), 53 }) 54 return &testTransport{rpub: rpub, rlpx: wrapped} 55 } 56 57 func (c *testTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *ecdsa.PublicKey) (*ecdsa.PublicKey, error) { 58 return c.rpub, nil 59 } 60 61 func (c *testTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) { 62 pubkey := crypto.FromECDSAPub(c.rpub)[1:] 63 return &protoHandshake{ID: pubkey, Name: "test"}, nil 64 } 65 66 func (c *testTransport) close(err error) { 67 c.rlpx.fd.Close() 68 c.closeErr = err 69 } 70 71 func startTestServer(t *testing.T, remoteKey *ecdsa.PublicKey, pf func(*Peer)) *Server { 72 config := Config{ 73 Name: "test", 74 MaxPeers: 10, 75 ListenAddr: "127.0.0.1:0", 76 PrivateKey: newkey(), 77 } 78 server := &Server{ 79 Config: config, 80 newPeerHook: pf, 81 newTransport: func(fd net.Conn) transport { return newTestTransport(remoteKey, fd) }, 82 } 83 if err := server.Start(); err != nil { 84 t.Fatalf("Could not start server: %v", err) 85 } 86 return server 87 } 88 89 func TestServerListen(t *testing.T) { 90 // start the test server 91 connected := make(chan *Peer) 92 remid := &newkey().PublicKey 93 srv := startTestServer(t, remid, func(p *Peer) { 94 if p.ID() != enode.PubkeyToIDV4(remid) { 95 t.Error("peer func called with wrong node id") 96 } 97 connected <- p 98 }) 99 defer close(connected) 100 defer srv.Stop() 101 102 // dial the test server 103 conn, err := net.DialTimeout("tcp", srv.ListenAddr, 5*time.Second) 104 if err != nil { 105 t.Fatalf("could not dial: %v", err) 106 } 107 defer conn.Close() 108 109 select { 110 case peer := <-connected: 111 if peer.LocalAddr().String() != conn.RemoteAddr().String() { 112 t.Errorf("peer started with wrong conn: got %v, want %v", 113 peer.LocalAddr(), conn.RemoteAddr()) 114 } 115 peers := srv.Peers() 116 if !reflect.DeepEqual(peers, []*Peer{peer}) { 117 t.Errorf("Peers mismatch: got %v, want %v", peers, []*Peer{peer}) 118 } 119 case <-time.After(1 * time.Second): 120 t.Error("server did not accept within one second") 121 } 122 } 123 124 func TestServerDial(t *testing.T) { 125 // run a one-shot TCP server to handle the connection. 126 listener, err := net.Listen("tcp", "127.0.0.1:0") 127 if err != nil { 128 t.Fatalf("could not setup listener: %v", err) 129 } 130 defer listener.Close() 131 accepted := make(chan net.Conn) 132 go func() { 133 conn, err := listener.Accept() 134 if err != nil { 135 t.Error("accept error:", err) 136 return 137 } 138 accepted <- conn 139 }() 140 141 // start the server 142 connected := make(chan *Peer) 143 remid := &newkey().PublicKey 144 srv := startTestServer(t, remid, func(p *Peer) { connected <- p }) 145 defer close(connected) 146 defer srv.Stop() 147 148 // tell the server to connect 149 tcpAddr := listener.Addr().(*net.TCPAddr) 150 node := enode.NewV4(remid, tcpAddr.IP, tcpAddr.Port, 0) 151 srv.AddPeer(node) 152 153 select { 154 case conn := <-accepted: 155 defer conn.Close() 156 157 select { 158 case peer := <-connected: 159 if peer.ID() != enode.PubkeyToIDV4(remid) { 160 t.Errorf("peer has wrong id") 161 } 162 if peer.Name() != "test" { 163 t.Errorf("peer has wrong name") 164 } 165 if peer.RemoteAddr().String() != conn.LocalAddr().String() { 166 t.Errorf("peer started with wrong conn: got %v, want %v", 167 peer.RemoteAddr(), conn.LocalAddr()) 168 } 169 peers := srv.Peers() 170 if !reflect.DeepEqual(peers, []*Peer{peer}) { 171 t.Errorf("Peers mismatch: got %v, want %v", peers, []*Peer{peer}) 172 } 173 174 // Test AddTrustedPeer/RemoveTrustedPeer and changing Trusted flags 175 // Particularly for race conditions on changing the flag state. 176 if peer := srv.Peers()[0]; peer.Info().Network.Trusted { 177 t.Errorf("peer is trusted prematurely: %v", peer) 178 } 179 done := make(chan bool) 180 go func() { 181 srv.AddTrustedPeer(node) 182 if peer := srv.Peers()[0]; !peer.Info().Network.Trusted { 183 t.Errorf("peer is not trusted after AddTrustedPeer: %v", peer) 184 } 185 srv.RemoveTrustedPeer(node) 186 if peer := srv.Peers()[0]; peer.Info().Network.Trusted { 187 t.Errorf("peer is trusted after RemoveTrustedPeer: %v", peer) 188 } 189 done <- true 190 }() 191 // Trigger potential race conditions 192 peer = srv.Peers()[0] 193 _ = peer.Inbound() 194 _ = peer.Info() 195 <-done 196 case <-time.After(1 * time.Second): 197 t.Error("server did not launch peer within one second") 198 } 199 200 case <-time.After(1 * time.Second): 201 t.Error("server did not connect within one second") 202 } 203 } 204 205 // This test checks that tasks generated by dialstate are 206 // actually executed and taskdone is called for them. 207 func TestServerTaskScheduling(t *testing.T) { 208 var ( 209 done = make(chan *testTask) 210 quit, returned = make(chan struct{}), make(chan struct{}) 211 tc = 0 212 tg = taskgen{ 213 newFunc: func(running int, peers map[enode.ID]*Peer) []task { 214 tc++ 215 return []task{&testTask{index: tc - 1}} 216 }, 217 doneFunc: func(t task) { 218 select { 219 case done <- t.(*testTask): 220 case <-quit: 221 } 222 }, 223 } 224 ) 225 226 // The Server in this test isn't actually running 227 // because we're only interested in what run does. 228 db, _ := enode.OpenDB("") 229 srv := &Server{ 230 Config: Config{MaxPeers: 10}, 231 localnode: enode.NewLocalNode(db, newkey()), 232 nodedb: db, 233 quit: make(chan struct{}), 234 ntab: fakeTable{}, 235 running: true, 236 log: log.New(), 237 } 238 srv.loopWG.Add(1) 239 go func() { 240 srv.run(tg) 241 close(returned) 242 }() 243 244 var gotdone []*testTask 245 for i := 0; i < 100; i++ { 246 gotdone = append(gotdone, <-done) 247 } 248 for i, task := range gotdone { 249 if task.index != i { 250 t.Errorf("task %d has wrong index, got %d", i, task.index) 251 break 252 } 253 if !task.called { 254 t.Errorf("task %d was not called", i) 255 break 256 } 257 } 258 259 close(quit) 260 srv.Stop() 261 select { 262 case <-returned: 263 case <-time.After(500 * time.Millisecond): 264 t.Error("Server.run did not return within 500ms") 265 } 266 } 267 268 // This test checks that Server doesn't drop tasks, 269 // even if newTasks returns more than the maximum number of tasks. 270 func TestServerManyTasks(t *testing.T) { 271 alltasks := make([]task, 300) 272 for i := range alltasks { 273 alltasks[i] = &testTask{index: i} 274 } 275 276 var ( 277 db, _ = enode.OpenDB("") 278 srv = &Server{ 279 quit: make(chan struct{}), 280 localnode: enode.NewLocalNode(db, newkey()), 281 nodedb: db, 282 ntab: fakeTable{}, 283 running: true, 284 log: log.New(), 285 } 286 done = make(chan *testTask) 287 start, end = 0, 0 288 ) 289 defer srv.Stop() 290 srv.loopWG.Add(1) 291 go srv.run(taskgen{ 292 newFunc: func(running int, peers map[enode.ID]*Peer) []task { 293 start, end = end, end+maxActiveDialTasks+10 294 if end > len(alltasks) { 295 end = len(alltasks) 296 } 297 return alltasks[start:end] 298 }, 299 doneFunc: func(tt task) { 300 done <- tt.(*testTask) 301 }, 302 }) 303 304 doneset := make(map[int]bool) 305 timeout := time.After(2 * time.Second) 306 for len(doneset) < len(alltasks) { 307 select { 308 case tt := <-done: 309 if doneset[tt.index] { 310 t.Errorf("task %d got done more than once", tt.index) 311 } else { 312 doneset[tt.index] = true 313 } 314 case <-timeout: 315 t.Errorf("%d of %d tasks got done within 2s", len(doneset), len(alltasks)) 316 for i := 0; i < len(alltasks); i++ { 317 if !doneset[i] { 318 t.Logf("task %d not done", i) 319 } 320 } 321 return 322 } 323 } 324 } 325 326 type taskgen struct { 327 newFunc func(running int, peers map[enode.ID]*Peer) []task 328 doneFunc func(task) 329 } 330 331 func (tg taskgen) newTasks(running int, peers map[enode.ID]*Peer, now time.Time) []task { 332 return tg.newFunc(running, peers) 333 } 334 func (tg taskgen) taskDone(t task, now time.Time) { 335 tg.doneFunc(t) 336 } 337 func (tg taskgen) addStatic(*enode.Node) { 338 } 339 func (tg taskgen) removeStatic(*enode.Node) { 340 } 341 342 type testTask struct { 343 index int 344 called bool 345 } 346 347 func (t *testTask) Do(srv *Server) { 348 t.called = true 349 } 350 351 // This test checks that connections are disconnected 352 // just after the encryption handshake when the server is 353 // at capacity. Trusted connections should still be accepted. 354 func TestServerAtCap(t *testing.T) { 355 trustedNode := newkey() 356 trustedID := enode.PubkeyToIDV4(&trustedNode.PublicKey) 357 srv := &Server{ 358 Config: Config{ 359 PrivateKey: newkey(), 360 MaxPeers: 10, 361 NoDial: true, 362 TrustedNodes: []*enode.Node{newNode(trustedID, nil)}, 363 }, 364 } 365 if err := srv.Start(); err != nil { 366 t.Fatalf("could not start: %v", err) 367 } 368 defer srv.Stop() 369 370 newconn := func(id enode.ID) *conn { 371 fd, _ := net.Pipe() 372 tx := newTestTransport(&trustedNode.PublicKey, fd) 373 node := enode.SignNull(new(enr.Record), id) 374 return &conn{fd: fd, transport: tx, flags: inboundConn, node: node, cont: make(chan error)} 375 } 376 377 // Inject a few connections to fill up the peer set. 378 for i := 0; i < 10; i++ { 379 c := newconn(randomID()) 380 if err := srv.checkpoint(c, srv.addpeer); err != nil { 381 t.Fatalf("could not add conn %d: %v", i, err) 382 } 383 } 384 // Try inserting a non-trusted connection. 385 anotherID := randomID() 386 c := newconn(anotherID) 387 if err := srv.checkpoint(c, srv.posthandshake); err != DiscTooManyPeers { 388 t.Error("wrong error for insert:", err) 389 } 390 // Try inserting a trusted connection. 391 c = newconn(trustedID) 392 if err := srv.checkpoint(c, srv.posthandshake); err != nil { 393 t.Error("unexpected error for trusted conn @posthandshake:", err) 394 } 395 if !c.is(trustedConn) { 396 t.Error("Server did not set trusted flag") 397 } 398 399 // Remove from trusted set and try again 400 srv.RemoveTrustedPeer(newNode(trustedID, nil)) 401 c = newconn(trustedID) 402 if err := srv.checkpoint(c, srv.posthandshake); err != DiscTooManyPeers { 403 t.Error("wrong error for insert:", err) 404 } 405 406 // Add anotherID to trusted set and try again 407 srv.AddTrustedPeer(newNode(anotherID, nil)) 408 c = newconn(anotherID) 409 if err := srv.checkpoint(c, srv.posthandshake); err != nil { 410 t.Error("unexpected error for trusted conn @posthandshake:", err) 411 } 412 if !c.is(trustedConn) { 413 t.Error("Server did not set trusted flag") 414 } 415 } 416 417 func TestServerPeerLimits(t *testing.T) { 418 srvkey := newkey() 419 clientkey := newkey() 420 clientnode := enode.NewV4(&clientkey.PublicKey, nil, 0, 0) 421 422 var tp = &setupTransport{ 423 pubkey: &clientkey.PublicKey, 424 phs: protoHandshake{ 425 ID: crypto.FromECDSAPub(&clientkey.PublicKey)[1:], 426 // Force "DiscUselessPeer" due to unmatching caps 427 // Caps: []Cap{discard.cap()}, 428 }, 429 } 430 431 srv := &Server{ 432 Config: Config{ 433 PrivateKey: srvkey, 434 MaxPeers: 0, 435 NoDial: true, 436 Protocols: []Protocol{discard}, 437 }, 438 newTransport: func(fd net.Conn) transport { return tp }, 439 log: log.New(), 440 } 441 if err := srv.Start(); err != nil { 442 t.Fatalf("couldn't start server: %v", err) 443 } 444 defer srv.Stop() 445 446 // Check that server is full (MaxPeers=0) 447 flags := dynDialedConn 448 dialDest := clientnode 449 conn, _ := net.Pipe() 450 srv.SetupConn(conn, flags, dialDest) 451 if tp.closeErr != DiscTooManyPeers { 452 t.Errorf("unexpected close error: %q", tp.closeErr) 453 } 454 conn.Close() 455 456 srv.AddTrustedPeer(clientnode) 457 458 // Check that server allows a trusted peer despite being full. 459 conn, _ = net.Pipe() 460 srv.SetupConn(conn, flags, dialDest) 461 if tp.closeErr == DiscTooManyPeers { 462 t.Errorf("failed to bypass MaxPeers with trusted node: %q", tp.closeErr) 463 } 464 465 if tp.closeErr != DiscUselessPeer { 466 t.Errorf("unexpected close error: %q", tp.closeErr) 467 } 468 conn.Close() 469 470 srv.RemoveTrustedPeer(clientnode) 471 472 // Check that server is full again. 473 conn, _ = net.Pipe() 474 srv.SetupConn(conn, flags, dialDest) 475 if tp.closeErr != DiscTooManyPeers { 476 t.Errorf("unexpected close error: %q", tp.closeErr) 477 } 478 conn.Close() 479 } 480 481 func TestServerSetupConn(t *testing.T) { 482 var ( 483 clientkey, srvkey = newkey(), newkey() 484 clientpub = &clientkey.PublicKey 485 srvpub = &srvkey.PublicKey 486 ) 487 tests := []struct { 488 dontstart bool 489 tt *setupTransport 490 flags connFlag 491 dialDest *enode.Node 492 493 wantCloseErr error 494 wantCalls string 495 }{ 496 { 497 dontstart: true, 498 tt: &setupTransport{pubkey: clientpub}, 499 wantCalls: "close,", 500 wantCloseErr: errServerStopped, 501 }, 502 { 503 tt: &setupTransport{pubkey: clientpub, encHandshakeErr: errors.New("read error")}, 504 flags: inboundConn, 505 wantCalls: "doEncHandshake,close,", 506 wantCloseErr: errors.New("read error"), 507 }, 508 { 509 tt: &setupTransport{pubkey: clientpub}, 510 dialDest: enode.NewV4(&newkey().PublicKey, nil, 0, 0), 511 flags: dynDialedConn, 512 wantCalls: "doEncHandshake,close,", 513 wantCloseErr: DiscUnexpectedIdentity, 514 }, 515 { 516 tt: &setupTransport{pubkey: clientpub, phs: protoHandshake{ID: randomID().Bytes()}}, 517 dialDest: enode.NewV4(clientpub, nil, 0, 0), 518 flags: dynDialedConn, 519 wantCalls: "doEncHandshake,doProtoHandshake,close,", 520 wantCloseErr: DiscUnexpectedIdentity, 521 }, 522 { 523 tt: &setupTransport{pubkey: clientpub, protoHandshakeErr: errors.New("foo")}, 524 dialDest: enode.NewV4(clientpub, nil, 0, 0), 525 flags: dynDialedConn, 526 wantCalls: "doEncHandshake,doProtoHandshake,close,", 527 wantCloseErr: errors.New("foo"), 528 }, 529 { 530 tt: &setupTransport{pubkey: srvpub, phs: protoHandshake{ID: crypto.FromECDSAPub(srvpub)[1:]}}, 531 flags: inboundConn, 532 wantCalls: "doEncHandshake,close,", 533 wantCloseErr: DiscSelf, 534 }, 535 { 536 tt: &setupTransport{pubkey: clientpub, phs: protoHandshake{ID: crypto.FromECDSAPub(clientpub)[1:]}}, 537 flags: inboundConn, 538 wantCalls: "doEncHandshake,doProtoHandshake,close,", 539 wantCloseErr: DiscUselessPeer, 540 }, 541 } 542 543 for i, test := range tests { 544 srv := &Server{ 545 Config: Config{ 546 PrivateKey: srvkey, 547 MaxPeers: 10, 548 NoDial: true, 549 Protocols: []Protocol{discard}, 550 }, 551 newTransport: func(fd net.Conn) transport { return test.tt }, 552 log: log.New(), 553 } 554 if !test.dontstart { 555 if err := srv.Start(); err != nil { 556 t.Fatalf("couldn't start server: %v", err) 557 } 558 } 559 p1, _ := net.Pipe() 560 srv.SetupConn(p1, test.flags, test.dialDest) 561 if !reflect.DeepEqual(test.tt.closeErr, test.wantCloseErr) { 562 t.Errorf("test %d: close error mismatch: got %q, want %q", i, test.tt.closeErr, test.wantCloseErr) 563 } 564 if test.tt.calls != test.wantCalls { 565 t.Errorf("test %d: calls mismatch: got %q, want %q", i, test.tt.calls, test.wantCalls) 566 } 567 } 568 } 569 570 type setupTransport struct { 571 pubkey *ecdsa.PublicKey 572 encHandshakeErr error 573 phs protoHandshake 574 protoHandshakeErr error 575 576 calls string 577 closeErr error 578 } 579 580 func (c *setupTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *ecdsa.PublicKey) (*ecdsa.PublicKey, error) { 581 c.calls += "doEncHandshake," 582 return c.pubkey, c.encHandshakeErr 583 } 584 585 func (c *setupTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) { 586 c.calls += "doProtoHandshake," 587 if c.protoHandshakeErr != nil { 588 return nil, c.protoHandshakeErr 589 } 590 return &c.phs, nil 591 } 592 func (c *setupTransport) close(err error) { 593 c.calls += "close," 594 c.closeErr = err 595 } 596 597 // setupConn shouldn't write to/read from the connection. 598 func (c *setupTransport) WriteMsg(Msg) error { 599 panic("WriteMsg called on setupTransport") 600 } 601 func (c *setupTransport) ReadMsg() (Msg, error) { 602 panic("ReadMsg called on setupTransport") 603 } 604 605 func newkey() *ecdsa.PrivateKey { 606 key, err := crypto.GenerateKey() 607 if err != nil { 608 panic("couldn't generate key: " + err.Error()) 609 } 610 return key 611 } 612 613 func randomID() (id enode.ID) { 614 for i := range id { 615 id[i] = byte(rand.Intn(255)) 616 } 617 return id 618 }