rlpxcmd.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2020 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. "net"
  20. "os"
  21. "github.com/ethereum/go-ethereum/cmd/devp2p/internal/ethtest"
  22. "github.com/ethereum/go-ethereum/crypto"
  23. "github.com/ethereum/go-ethereum/internal/utesting"
  24. "github.com/ethereum/go-ethereum/p2p"
  25. "github.com/ethereum/go-ethereum/p2p/rlpx"
  26. "github.com/ethereum/go-ethereum/rlp"
  27. "gopkg.in/urfave/cli.v1"
  28. )
  29. var (
  30. rlpxCommand = cli.Command{
  31. Name: "rlpx",
  32. Usage: "RLPx Commands",
  33. Subcommands: []cli.Command{
  34. rlpxPingCommand,
  35. rlpxEthTestCommand,
  36. },
  37. }
  38. rlpxPingCommand = cli.Command{
  39. Name: "ping",
  40. Usage: "ping <node>",
  41. Action: rlpxPing,
  42. }
  43. rlpxEthTestCommand = cli.Command{
  44. Name: "eth-test",
  45. Usage: "Runs tests against a node",
  46. ArgsUsage: "<node> <path_to_chain.rlp_file>",
  47. Action: rlpxEthTest,
  48. Flags: []cli.Flag{testPatternFlag},
  49. }
  50. )
  51. func rlpxPing(ctx *cli.Context) error {
  52. n := getNodeArg(ctx)
  53. fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", n.IP(), n.TCP()))
  54. if err != nil {
  55. return err
  56. }
  57. conn := rlpx.NewConn(fd, n.Pubkey())
  58. ourKey, _ := crypto.GenerateKey()
  59. _, err = conn.Handshake(ourKey)
  60. if err != nil {
  61. return err
  62. }
  63. code, data, _, err := conn.Read()
  64. if err != nil {
  65. return err
  66. }
  67. switch code {
  68. case 0:
  69. var h ethtest.Hello
  70. if err := rlp.DecodeBytes(data, &h); err != nil {
  71. return fmt.Errorf("invalid handshake: %v", err)
  72. }
  73. fmt.Printf("%+v\n", h)
  74. case 1:
  75. var msg []p2p.DiscReason
  76. if rlp.DecodeBytes(data, &msg); len(msg) == 0 {
  77. return fmt.Errorf("invalid disconnect message")
  78. }
  79. return fmt.Errorf("received disconnect message: %v", msg[0])
  80. default:
  81. return fmt.Errorf("invalid message code %d, expected handshake (code zero)", code)
  82. }
  83. return nil
  84. }
  85. func rlpxEthTest(ctx *cli.Context) error {
  86. if ctx.NArg() < 3 {
  87. exit("missing path to chain.rlp as command-line argument")
  88. }
  89. suite := ethtest.NewSuite(getNodeArg(ctx), ctx.Args()[1], ctx.Args()[2])
  90. // Filter and run test cases.
  91. tests := suite.AllTests()
  92. if ctx.IsSet(testPatternFlag.Name) {
  93. tests = utesting.MatchTests(tests, ctx.String(testPatternFlag.Name))
  94. }
  95. results := utesting.RunTests(tests, os.Stdout)
  96. if fails := utesting.CountFailures(results); fails > 0 {
  97. return fmt.Errorf("%v of %v tests passed.", len(tests)-fails, len(tests))
  98. }
  99. fmt.Printf("all tests passed\n")
  100. return nil
  101. }