cmd/devp2p: add eth protocol test suite (#21598)

This change adds a test framework for the "eth" protocol and some basic
tests. The tests can be run using the './devp2p rlpx eth-test' command.
This commit is contained in:
rene
2020-09-23 15:18:17 +02:00
committed by GitHub
parent c1544423d6
commit a25899f3dc
11 changed files with 628 additions and 37 deletions

View File

@ -19,9 +19,11 @@ package main
import (
"fmt"
"net"
"os"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/cmd/devp2p/internal/ethtest"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/internal/utesting"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/rlpx"
"github.com/ethereum/go-ethereum/rlp"
@ -34,38 +36,42 @@ var (
Usage: "RLPx Commands",
Subcommands: []cli.Command{
rlpxPingCommand,
rlpxEthTestCommand,
},
}
rlpxPingCommand = cli.Command{
Name: "ping",
Usage: "Perform a RLPx handshake",
ArgsUsage: "<node>",
Action: rlpxPing,
Name: "ping",
Usage: "ping <node>",
Action: rlpxPing,
}
rlpxEthTestCommand = cli.Command{
Name: "eth-test",
Usage: "Runs tests against a node",
ArgsUsage: "<node> <path_to_chain.rlp_file>",
Action: rlpxEthTest,
Flags: []cli.Flag{testPatternFlag},
}
)
func rlpxPing(ctx *cli.Context) error {
n := getNodeArg(ctx)
fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", n.IP(), n.TCP()))
if err != nil {
return err
}
conn := rlpx.NewConn(fd, n.Pubkey())
ourKey, _ := crypto.GenerateKey()
_, err = conn.Handshake(ourKey)
if err != nil {
return err
}
code, data, _, err := conn.Read()
if err != nil {
return err
}
switch code {
case 0:
var h devp2pHandshake
var h ethtest.Hello
if err := rlp.DecodeBytes(data, &h); err != nil {
return fmt.Errorf("invalid handshake: %v", err)
}
@ -82,13 +88,22 @@ func rlpxPing(ctx *cli.Context) error {
return nil
}
// devp2pHandshake is the RLP structure of the devp2p protocol handshake.
type devp2pHandshake struct {
Version uint64
Name string
Caps []p2p.Cap
ListenPort uint64
ID hexutil.Bytes // secp256k1 public key
// Ignore additional fields (for forward compatibility).
Rest []rlp.RawValue `rlp:"tail"`
func rlpxEthTest(ctx *cli.Context) error {
if ctx.NArg() < 3 {
exit("missing path to chain.rlp as command-line argument")
}
suite := ethtest.NewSuite(getNodeArg(ctx), ctx.Args()[1], ctx.Args()[2])
// Filter and run test cases.
tests := suite.AllTests()
if ctx.IsSet(testPatternFlag.Name) {
tests = utesting.MatchTests(tests, ctx.String(testPatternFlag.Name))
}
results := utesting.RunTests(tests, os.Stdout)
if fails := utesting.CountFailures(results); fails > 0 {
return fmt.Errorf("%v of %v tests passed.", len(tests)-fails, len(tests))
}
fmt.Printf("all tests passed\n")
return nil
}