zcash: recursively ask new peers for their address book

This commit is contained in:
George Tankersley 2020-05-29 16:50:25 -04:00
parent 3afe386840
commit 3cc28746f6
3 changed files with 30 additions and 19 deletions

View File

@ -70,7 +70,7 @@ func setup(c *caddy.Controller) error {
}
// Connect to the bootstrap peer
err = seeder.Connect(address, port)
_, err = seeder.Connect(address, port)
if err != nil {
return plugin.Error(pluginName, c.Errf("error connecting to %s:%s: %v", address, port, err))
}

View File

@ -156,21 +156,25 @@ func (s *Seeder) GetNetworkDefaultPort() string {
// the peer. Otherwise it returns nil and adds the peer to the list of live
// connections and known-good addresses.
func (s *Seeder) ConnectOnDefaultPort(addr string) error {
return s.Connect(addr, s.config.ChainParams.DefaultPort)
_, err := s.Connect(addr, s.config.ChainParams.DefaultPort)
return err
}
func (s *Seeder) Connect(addr, port string) error {
// Connect attempts to connect to a peer at the given address and port. It
// returns a handle to the peer connection if the connection is successful
// or nil and an error if it fails.
func (s *Seeder) Connect(addr, port string) (*peer.Peer, error) {
connectionString := net.JoinHostPort(addr, port)
p, err := peer.NewOutboundPeer(s.config, connectionString)
if err != nil {
return errors.Wrap(err, "constructing outbound peer")
return nil, errors.Wrap(err, "constructing outbound peer")
}
// PeerKeys are used in our internal maps to keep signals and responses from specific peers straight.
pk := peerKeyFromPeer(p)
if s.addrBook.IsBlacklisted(pk) {
return ErrBlacklistedPeer
return nil, ErrBlacklistedPeer
}
_, alreadyPending := s.pendingPeers.Load(pk)
@ -179,24 +183,24 @@ func (s *Seeder) Connect(addr, port string) error {
if alreadyPending {
s.logger.Printf("Peer is already pending: %s", p.Addr())
return ErrRepeatConnection
return nil, ErrRepeatConnection
}
s.pendingPeers.Store(pk, p)
if alreadyHandshaking {
s.logger.Printf("Peer is already handshaking: %s", p.Addr())
return ErrRepeatConnection
return nil, ErrRepeatConnection
}
s.handshakeSignals.Store(pk, make(chan struct{}, 1))
if alreadyLive {
s.logger.Printf("Peer is already live: %s", p.Addr())
return ErrRepeatConnection
return nil, ErrRepeatConnection
}
conn, err := net.DialTimeout("tcp", p.Addr(), connectionDialTimeout)
if err != nil {
return errors.Wrap(err, "dialing peer address")
return nil, errors.Wrap(err, "dialing peer address")
}
// Begin connection negotiation.
@ -210,9 +214,9 @@ func (s *Seeder) Connect(addr, port string) error {
case <-handshakeChan.(chan struct{}):
s.logger.Printf("Handshake completed with peer %s", p.Addr())
s.handshakeSignals.Delete(pk)
return nil
return p, nil
case <-time.After(maximumHandshakeWait):
return errors.New("peer handshake started but timed out")
return nil, errors.New("peer handshake started but timed out")
}
panic("This should be unreachable")
@ -346,7 +350,7 @@ func (s *Seeder) RequestAddresses() int {
}
portString := strconv.Itoa(int(na.Port))
err := s.Connect(na.IP.String(), portString)
newPeer, err := s.Connect(na.IP.String(), portString)
if err != nil {
if err == ErrRepeatConnection {
@ -361,7 +365,10 @@ func (s *Seeder) RequestAddresses() int {
continue
}
s.DisconnectPeer(potentialPeer)
// Ask the newly discovered peer if they know anyone we haven't met yet.
newPeer.QueueMessage(wire.NewMsgGetAddr(), nil)
//s.DisconnectPeer(potentialPeer)
s.logger.Printf("Successfully learned about %s:%d.", na.IP, na.Port)
atomic.AddInt32(&peerCount, 1)
@ -399,7 +406,8 @@ func (s *Seeder) RefreshAddresses(disconnect bool) {
ipString := na.IP.String()
portString := strconv.Itoa(int(na.Port))
err := s.Connect(ipString, portString)
// Don't care about the peer individually, just that we can connect.
_, err := s.Connect(ipString, portString)
if err != nil {
if err != ErrRepeatConnection {
@ -448,7 +456,7 @@ func (s *Seeder) RetryBlacklist() {
ipString := na.IP.String()
portString := strconv.Itoa(int(na.Port))
err := s.Connect(ipString, portString)
_, err := s.Connect(ipString, portString)
if err != nil {
// Connection failed. Peer remains blacklisted.

View File

@ -226,14 +226,17 @@ func TestBlacklist(t *testing.T) {
t.Errorf("Error getting one mocked address: %v", err)
}
regSeeder.testBlacklist(PeerKey("127.0.0.1:12345"))
err = regSeeder.Connect("127.0.0.1", "12345")
workingTestPeer := PeerKey("127.0.0.1:12345")
regSeeder.testBlacklist(workingTestPeer)
_, err = regSeeder.Connect("127.0.0.1", "12345")
if err != ErrBlacklistedPeer {
t.Errorf("Blacklist did not prevent connection")
}
regSeeder.DisconnectPeer(workingTestPeer)
regSeeder.testRedeem(PeerKey("127.0.0.1:12345"))
err = regSeeder.Connect("127.0.0.1", "12345")
regSeeder.testRedeem(workingTestPeer)
_, err = regSeeder.Connect("127.0.0.1", "12345")
if err != nil {
t.Errorf("Redeem didn't allow reconnecting")
}