rlpxcmd.go 2.9 KB

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