diff --git a/zcash/client_callbacks.go b/zcash/client_callbacks.go index 6103892..1f42ff5 100644 --- a/zcash/client_callbacks.go +++ b/zcash/client_callbacks.go @@ -37,14 +37,9 @@ func (s *Seeder) onVerAck(p *peer.Peer, msg *wire.MsgVerAck) { return } - // Add to list of known good addresses if we don't already have it. - // Otherwise, update the last-valid time. - + // If we've already connected to this peer, update the last-valid time. if s.addrBook.IsKnown(pk) { s.addrBook.Touch(pk) - } else { - s.logger.Printf("Adding %s to address list", pk) - s.addrBook.Add(pk) } return @@ -103,15 +98,21 @@ func (s *Seeder) onAddr(p *peer.Peer, msg *wire.MsgAddr) { err := s.Connect(na.IP.String(), portString) if err != nil { - s.logger.Printf("Got unusable peer %s:%d from peer %s. Error: %s", na.IP, na.Port, p.Addr(), err) + if err == ErrRepeatConnection { + s.logger.Printf("Got duplicate peer %s:%d from peer %s. Error: %s", na.IP, na.Port, p.Addr(), err) + continue + } // Blacklist the potential peer. We might try to connect again later, // since we assume IsRoutable filtered out the truly wrong ones. + s.logger.Printf("Got unusable peer %s:%d from peer %s. Error: %s", na.IP, na.Port, p.Addr(), err) s.addrBook.Blacklist(potentialPeer) continue } s.DisconnectPeer(potentialPeer) + + s.logger.Printf("Successfully learned about %s:%d from %s.", na.IP, na.Port, p.Addr()) s.addrBook.Add(potentialPeer) } }() diff --git a/zcash/client_test.go b/zcash/client_test.go index e4ff075..1b66a7d 100644 --- a/zcash/client_test.go +++ b/zcash/client_test.go @@ -1,6 +1,7 @@ package zcash import ( + "fmt" "net" "os" "sync" @@ -14,16 +15,20 @@ import ( ) func TestMain(m *testing.M) { - startMockLoop() + err := startMockLoop() + if err != nil { + fmt.Printf("Failed to start mock loop!") + os.Exit(1) + } exitCode := m.Run() os.Exit(exitCode) } -func startMockLoop() { +func startMockLoop() error { // Configure peer to act as a regtest node that offers no services. config, err := newSeederPeerConfig(network.Regtest, defaultPeerConfig) if err != nil { - return + return err } config.AllowSelfConns = true @@ -35,34 +40,50 @@ func startMockLoop() { config.Listeners.OnGetAddr = func(p *peer.Peer, msg *wire.MsgGetAddr) { cache := make([]*wire.NetAddress, 0, 1) + + // This will an unusable peer (testnet port) addr := wire.NewNetAddressTimestamp( time.Now(), 0, net.ParseIP("127.0.0.1"), uint16(18233), ) + + // This will be an unusable peer (bs port) addr2 := wire.NewNetAddressTimestamp( time.Now(), 0, net.ParseIP("127.0.0.1"), - uint16(18344), + uint16(31337), ) - cache = append(cache, addr, addr2) + + // This will be a usable peer, corresponding to our second listener. + addr3 := wire.NewNetAddressTimestamp( + time.Now(), + 0, + net.ParseIP("127.0.0.1"), + uint16(12345), + ) + + cache = append(cache, addr, addr2, addr3) _, err := p.PushAddrMsg(cache) if err != nil { mockPeerLogger.Error(err) } } - listenAddr := net.JoinHostPort("127.0.0.1", config.ChainParams.DefaultPort) - listener, err := net.Listen("tcp", listenAddr) + listener1, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", config.ChainParams.DefaultPort)) if err != nil { - return + return err + } + listener2, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", "12345")) + if err != nil { + return err } go func() { for { - conn, err := listener.Accept() + conn, err := listener1.Accept() if err != nil { return } @@ -71,6 +92,21 @@ func startMockLoop() { mockPeer.AssociateConnection(conn) } }() + + go func() { + for { + conn, err := listener2.Accept() + if err != nil { + return + } + defaultConfig, _ := newSeederPeerConfig(network.Regtest, defaultPeerConfig) + defaultConfig.AllowSelfConns = true + mockPeer := peer.NewInboundPeer(defaultConfig) + mockPeer.AssociateConnection(conn) + } + }() + + return nil } func TestOutboundPeerSync(t *testing.T) {