Skip to content

Commit 129cf07

Browse files
renaynayfjl
andauthored
p2p: move rlpx into separate package (#21464)
This change moves the RLPx protocol implementation into a separate package, p2p/rlpx. The new package can be used to establish RLPx connections for protocol testing purposes. Co-authored-by: Felix Lange <[email protected]>
1 parent 2c097bb commit 129cf07

File tree

10 files changed

+901
-742
lines changed

10 files changed

+901
-742
lines changed

cmd/devp2p/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func init() {
6363
discv5Command,
6464
dnsCommand,
6565
nodesetCommand,
66+
rlpxCommand,
6667
}
6768
}
6869

cmd/devp2p/rlpxcmd.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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+
17+
package main
18+
19+
import (
20+
"fmt"
21+
"net"
22+
23+
"github.com/ethereum/go-ethereum/common/hexutil"
24+
"github.com/ethereum/go-ethereum/crypto"
25+
"github.com/ethereum/go-ethereum/p2p"
26+
"github.com/ethereum/go-ethereum/p2p/rlpx"
27+
"github.com/ethereum/go-ethereum/rlp"
28+
"gopkg.in/urfave/cli.v1"
29+
)
30+
31+
var (
32+
rlpxCommand = cli.Command{
33+
Name: "rlpx",
34+
Usage: "RLPx Commands",
35+
Subcommands: []cli.Command{
36+
rlpxPingCommand,
37+
},
38+
}
39+
rlpxPingCommand = cli.Command{
40+
Name: "ping",
41+
Usage: "Perform a RLPx handshake",
42+
ArgsUsage: "<node>",
43+
Action: rlpxPing,
44+
}
45+
)
46+
47+
func rlpxPing(ctx *cli.Context) error {
48+
n := getNodeArg(ctx)
49+
50+
fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", n.IP(), n.TCP()))
51+
if err != nil {
52+
return err
53+
}
54+
conn := rlpx.NewConn(fd, n.Pubkey())
55+
56+
ourKey, _ := crypto.GenerateKey()
57+
_, err = conn.Handshake(ourKey)
58+
if err != nil {
59+
return err
60+
}
61+
62+
code, data, _, err := conn.Read()
63+
if err != nil {
64+
return err
65+
}
66+
switch code {
67+
case 0:
68+
var h devp2pHandshake
69+
if err := rlp.DecodeBytes(data, &h); err != nil {
70+
return fmt.Errorf("invalid handshake: %v", err)
71+
}
72+
fmt.Printf("%+v\n", h)
73+
case 1:
74+
var msg []p2p.DiscReason
75+
if rlp.DecodeBytes(data, &msg); len(msg) == 0 {
76+
return fmt.Errorf("invalid disconnect message")
77+
}
78+
return fmt.Errorf("received disconnect message: %v", msg[0])
79+
default:
80+
return fmt.Errorf("invalid message code %d, expected handshake (code zero)", code)
81+
}
82+
return nil
83+
}
84+
85+
// devp2pHandshake is the RLP structure of the devp2p protocol handshake.
86+
type devp2pHandshake struct {
87+
Version uint64
88+
Name string
89+
Caps []p2p.Cap
90+
ListenPort uint64
91+
ID hexutil.Bytes // secp256k1 public key
92+
// Ignore additional fields (for forward compatibility).
93+
Rest []rlp.RawValue `rlp:"tail"`
94+
}

p2p/message_test.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ package p2p
1818

1919
import (
2020
"bytes"
21-
"encoding/hex"
2221
"fmt"
2322
"io"
2423
"runtime"
25-
"strings"
2624
"testing"
2725
"time"
2826
)
@@ -141,12 +139,3 @@ func TestEOFSignal(t *testing.T) {
141139
default:
142140
}
143141
}
144-
145-
func unhex(str string) []byte {
146-
r := strings.NewReplacer("\t", "", " ", "", "\n", "")
147-
b, err := hex.DecodeString(r.Replace(str))
148-
if err != nil {
149-
panic(fmt.Sprintf("invalid hex string: %q", str))
150-
}
151-
return b
152-
}

p2p/peer_test.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,15 @@ func newNode(id enode.ID, addr string) *enode.Node {
8686
}
8787

8888
func testPeer(protos []Protocol) (func(), *conn, *Peer, <-chan error) {
89-
fd1, fd2 := net.Pipe()
90-
c1 := &conn{fd: fd1, node: newNode(randomID(), ""), transport: newTestTransport(&newkey().PublicKey, fd1)}
91-
c2 := &conn{fd: fd2, node: newNode(randomID(), ""), transport: newTestTransport(&newkey().PublicKey, fd2)}
89+
var (
90+
fd1, fd2 = net.Pipe()
91+
key1, key2 = newkey(), newkey()
92+
t1 = newTestTransport(&key2.PublicKey, fd1, nil)
93+
t2 = newTestTransport(&key1.PublicKey, fd2, &key1.PublicKey)
94+
)
95+
96+
c1 := &conn{fd: fd1, node: newNode(uintID(1), ""), transport: t1}
97+
c2 := &conn{fd: fd2, node: newNode(uintID(2), ""), transport: t2}
9298
for _, p := range protos {
9399
c1.caps = append(c1.caps, p.cap())
94100
c2.caps = append(c2.caps, p.cap())
@@ -173,9 +179,12 @@ func TestPeerPing(t *testing.T) {
173179
}
174180
}
175181

182+
// This test checks that a disconnect message sent by a peer is returned
183+
// as the error from Peer.run.
176184
func TestPeerDisconnect(t *testing.T) {
177185
closer, rw, _, disc := testPeer(nil)
178186
defer closer()
187+
179188
if err := SendItems(rw, discMsg, DiscQuitting); err != nil {
180189
t.Fatal(err)
181190
}

0 commit comments

Comments
 (0)