Help us shape the future of Go! Take the 2026 Go Developer Survey

ping

package
v0.1.92 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2025 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),
	PreRunE: func(cmd *cobra.Command, args []string) (err error) {
		inputPingParams.privateKey, err = p2p.ParsePrivateKey(inputPingParams.KeyFile, inputPingParams.PrivateKey)
		if err != nil {
			return err
		}

		return nil
	},
	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(p2p.NodeSet)

		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
				)

				opts := p2p.DialOpts{
					EnableWit:  inputPingParams.EnableWit,
					Port:       inputPingParams.Port,
					Addr:       inputPingParams.Addr,
					PrivateKey: inputPingParams.privateKey,
				}

				conn, err := p2p.Dial(node, opts)
				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 && inputPingParams.Listen {

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

				mutex.Lock()
				if _, ok := output[node.ID()]; !ok {
					output[node.ID()] = []p2p.NodeJSON{}
				}

				result := p2p.NodeJSON{
					URL:    node.URLv4(),
					Hello:  hello,
					Status: status,
					Time:   time.Now().Unix(),
				}
				if err != nil {
					result.Error = err.Error()
				}

				output[node.ID()] = append(output[node.ID()], result)
				mutex.Unlock()
			}(n)
		}
		wg.Wait()

		return p2p.WriteNodeSet(inputPingParams.OutputFile, output, true)
	},
}

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