ping

package
v0.1.43 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 16, 2024 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var PingCmd = &cobra.Command{
	Use:   "ping [enode/enr or nodes file]",
	Short: "Ping node(s) and return the output.",
	Long: `Ping nodes by either giving a single enode/enr or an entire nodes file.

This command will establish a handshake and status exchange to get the Hello and
Status messages and output JSON. If providing a enode/enr rather than a nodes
file, then the connection will remain open by default (--listen=true), and you
can see other messages the peer sends (e.g. blocks, transactions, etc.).`,
	Args: cobra.MinimumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		nodes := []*enode.Node{}
		if input, err := p2p.ReadNodeSet(args[0]); err == nil {
			nodes = input
		} else if node, err := p2p.ParseNode(args[0]); err == nil {
			nodes = append(nodes, node)
		} else {
			return err
		}

		output := make(pingNodeSet)

		var (
			mutex sync.Mutex
			wg    sync.WaitGroup
		)

		wg.Add(len(nodes))
		sem := make(chan bool, inputPingParams.Threads)

		count := &p2p.MessageCount{}
		go func() {
			ticker := time.NewTicker(2 * time.Second)
			for {
				<-ticker.C
				c := count.Load()
				if !c.IsEmpty() {
					log.Info().Interface("counts", c).Send()
					count.Clear()
				}
			}
		}()

		for _, n := range nodes {
			sem <- true
			go func(node *enode.Node) {
				defer func() {
					<-sem
					wg.Done()
				}()

				var (
					hello  *p2p.Hello
					status *p2p.Status
					errStr string
				)

				conn, err := p2p.Dial(node)
				if err != nil {
					log.Error().Err(err).Msg("Dial failed")
				} else {
					defer conn.Close()
					if hello, status, err = conn.Peer(); err != nil {
						log.Error().Err(err).Msg("Peer failed")
					}

					log.Info().Interface("hello", hello).Interface("status", status).Msg("Peering messages received")
				}

				if err != nil {
					errStr = err.Error()
				} else if inputPingParams.Listen {

					if err := conn.ReadAndServe(count); err != nil {
						log.Error().Err(err).Msg("Received error")
					}
				}

				mutex.Lock()
				output[node.ID()] = pingNodeJSON{
					Record: node,
					Hello:  hello,
					Status: status,
					Error:  errStr,
				}
				mutex.Unlock()
			}(n)
		}
		wg.Wait()

		nodesJSON, err := json.MarshalIndent(output, "", "  ")
		if err != nil {
			return err
		}

		if inputPingParams.OutputFile == "" {
			os.Stdout.Write(nodesJSON)
		} else if err := os.WriteFile(inputPingParams.OutputFile, nodesJSON, 0644); err != nil {
			return err
		}

		return nil
	},
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL