discv5cmd.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright 2019 The go-ethereum Authors
  2. // This file is part of go-ethereum.
  3. //
  4. // go-ethereum is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // go-ethereum is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  16. package main
  17. import (
  18. "fmt"
  19. "time"
  20. "github.com/ethereum/go-ethereum/cmd/devp2p/internal/v5test"
  21. "github.com/ethereum/go-ethereum/common"
  22. "github.com/ethereum/go-ethereum/p2p/discover"
  23. "gopkg.in/urfave/cli.v1"
  24. )
  25. var (
  26. discv5Command = cli.Command{
  27. Name: "discv5",
  28. Usage: "Node Discovery v5 tools",
  29. Subcommands: []cli.Command{
  30. discv5PingCommand,
  31. discv5ResolveCommand,
  32. discv5CrawlCommand,
  33. discv5TestCommand,
  34. discv5ListenCommand,
  35. },
  36. }
  37. discv5PingCommand = cli.Command{
  38. Name: "ping",
  39. Usage: "Sends ping to a node",
  40. Action: discv5Ping,
  41. }
  42. discv5ResolveCommand = cli.Command{
  43. Name: "resolve",
  44. Usage: "Finds a node in the DHT",
  45. Action: discv5Resolve,
  46. Flags: []cli.Flag{bootnodesFlag},
  47. }
  48. discv5CrawlCommand = cli.Command{
  49. Name: "crawl",
  50. Usage: "Updates a nodes.json file with random nodes found in the DHT",
  51. Action: discv5Crawl,
  52. Flags: []cli.Flag{bootnodesFlag, crawlTimeoutFlag},
  53. }
  54. discv5TestCommand = cli.Command{
  55. Name: "test",
  56. Usage: "Runs protocol tests against a node",
  57. Action: discv5Test,
  58. Flags: []cli.Flag{
  59. testPatternFlag,
  60. testTAPFlag,
  61. testListen1Flag,
  62. testListen2Flag,
  63. },
  64. }
  65. discv5ListenCommand = cli.Command{
  66. Name: "listen",
  67. Usage: "Runs a node",
  68. Action: discv5Listen,
  69. Flags: []cli.Flag{
  70. bootnodesFlag,
  71. nodekeyFlag,
  72. nodedbFlag,
  73. listenAddrFlag,
  74. },
  75. }
  76. )
  77. func discv5Ping(ctx *cli.Context) error {
  78. n := getNodeArg(ctx)
  79. disc := startV5(ctx)
  80. defer disc.Close()
  81. fmt.Println(disc.Ping(n))
  82. return nil
  83. }
  84. func discv5Resolve(ctx *cli.Context) error {
  85. n := getNodeArg(ctx)
  86. disc := startV5(ctx)
  87. defer disc.Close()
  88. fmt.Println(disc.Resolve(n))
  89. return nil
  90. }
  91. func discv5Crawl(ctx *cli.Context) error {
  92. if ctx.NArg() < 1 {
  93. return fmt.Errorf("need nodes file as argument")
  94. }
  95. nodesFile := ctx.Args().First()
  96. var inputSet nodeSet
  97. if common.FileExist(nodesFile) {
  98. inputSet = loadNodesJSON(nodesFile)
  99. }
  100. disc := startV5(ctx)
  101. defer disc.Close()
  102. c := newCrawler(inputSet, disc, disc.RandomNodes())
  103. c.revalidateInterval = 10 * time.Minute
  104. output := c.run(ctx.Duration(crawlTimeoutFlag.Name))
  105. writeNodesJSON(nodesFile, output)
  106. return nil
  107. }
  108. // discv5Test runs the protocol test suite.
  109. func discv5Test(ctx *cli.Context) error {
  110. suite := &v5test.Suite{
  111. Dest: getNodeArg(ctx),
  112. Listen1: ctx.String(testListen1Flag.Name),
  113. Listen2: ctx.String(testListen2Flag.Name),
  114. }
  115. return runTests(ctx, suite.AllTests())
  116. }
  117. func discv5Listen(ctx *cli.Context) error {
  118. disc := startV5(ctx)
  119. defer disc.Close()
  120. fmt.Println(disc.Self())
  121. select {}
  122. }
  123. // startV5 starts an ephemeral discovery v5 node.
  124. func startV5(ctx *cli.Context) *discover.UDPv5 {
  125. ln, config := makeDiscoveryConfig(ctx)
  126. socket := listen(ln, ctx.String(listenAddrFlag.Name))
  127. disc, err := discover.ListenV5(socket, ln, config)
  128. if err != nil {
  129. exit(err)
  130. }
  131. return disc
  132. }