rlpxcmd.go 2.7 KB

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