code: func (p *Peer) Info() *PeerInfo {
  	// Gather the protocol capabilities
  	var caps []string
  	for _, cap := range p.Caps() {
  		caps = append(caps, cap.String())
  	}
  	// Assemble the generic peer metadata
  	info := &PeerInfo{
  		Enode:     p.Node().String(),
  		ID:        p.ID().String(),
  		Name:      p.Name(),
  		Caps:      caps,
  		Protocols: make(map[string]interface{}),
  	}
  	info.Network.LocalAddress = p.LocalAddr().String()
  	info.Network.RemoteAddress = p.RemoteAddr().String()
  	info.Network.Inbound = p.rw.is(inboundConn)
  	info.Network.Trusted = p.rw.is(trustedConn)
  	info.Network.Static = p.rw.is(staticDialedConn)
  
  	// Gather all the running protocol infos
  	for _, proto := range p.running {
  		protoInfo := interface{}("unknown")
  		if query := proto.Protocol.PeerInfo; query != nil {
  			if metadata := query(p.ID()); metadata != nil {
  				protoInfo = metadata
  			} else {
  				protoInfo = "handshake"
  			}
  		}
  		info.Protocols[proto.Name] = protoInfo
  	}
  	return info
  }
docs: // Info gathers and returns a collection of metadata known about a peer.