Skip to content

Commit 6ce4670

Browse files
authored
cmd/devp2p: implement snap protocol testing (#24276)
This also contains some changes to the protocol handler to make the tests pass.
1 parent aaca58a commit 6ce4670

File tree

9 files changed

+864
-18
lines changed

9 files changed

+864
-18
lines changed

cmd/devp2p/internal/ethtest/chain.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"os"
2727
"strings"
2828

29+
"github.com/ethereum/go-ethereum/common"
2930
"github.com/ethereum/go-ethereum/core"
3031
"github.com/ethereum/go-ethereum/core/forkid"
3132
"github.com/ethereum/go-ethereum/core/types"
@@ -67,6 +68,13 @@ func (c *Chain) TotalDifficultyAt(height int) *big.Int {
6768
return sum
6869
}
6970

71+
func (c *Chain) RootAt(height int) common.Hash {
72+
if height < c.Len() {
73+
return c.blocks[height].Root()
74+
}
75+
return common.Hash{}
76+
}
77+
7078
// ForkID gets the fork id of the chain.
7179
func (c *Chain) ForkID() forkid.ID {
7280
return forkid.NewID(c.chainConfig, c.blocks[0].Hash(), uint64(c.Len()))

cmd/devp2p/internal/ethtest/helpers.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ func (s *Suite) dial66() (*Conn, error) {
9696
return conn, nil
9797
}
9898

99+
// dial66 attempts to dial the given node and perform a handshake,
100+
// returning the created Conn with additional snap/1 capabilities if
101+
// successful.
102+
func (s *Suite) dialSnap() (*Conn, error) {
103+
conn, err := s.dial66()
104+
if err != nil {
105+
return nil, fmt.Errorf("dial failed: %v", err)
106+
}
107+
conn.caps = append(conn.caps, p2p.Cap{Name: "snap", Version: 1})
108+
conn.ourHighestSnapProtoVersion = 1
109+
return conn, nil
110+
}
111+
99112
// peer performs both the protocol handshake and the status message
100113
// exchange with the node in order to peer with it.
101114
func (c *Conn) peer(chain *Chain, status *Status) error {
@@ -131,7 +144,11 @@ func (c *Conn) handshake() error {
131144
}
132145
c.negotiateEthProtocol(msg.Caps)
133146
if c.negotiatedProtoVersion == 0 {
134-
return fmt.Errorf("could not negotiate protocol (remote caps: %v, local eth version: %v)", msg.Caps, c.ourHighestProtoVersion)
147+
return fmt.Errorf("could not negotiate eth protocol (remote caps: %v, local eth version: %v)", msg.Caps, c.ourHighestProtoVersion)
148+
}
149+
// If we require snap, verify that it was negotiated
150+
if c.ourHighestSnapProtoVersion != c.negotiatedSnapProtoVersion {
151+
return fmt.Errorf("could not negotiate snap protocol (remote caps: %v, local snap version: %v)", msg.Caps, c.ourHighestSnapProtoVersion)
135152
}
136153
return nil
137154
default:
@@ -143,15 +160,21 @@ func (c *Conn) handshake() error {
143160
// advertised capability from peer.
144161
func (c *Conn) negotiateEthProtocol(caps []p2p.Cap) {
145162
var highestEthVersion uint
163+
var highestSnapVersion uint
146164
for _, capability := range caps {
147-
if capability.Name != "eth" {
148-
continue
149-
}
150-
if capability.Version > highestEthVersion && capability.Version <= c.ourHighestProtoVersion {
151-
highestEthVersion = capability.Version
165+
switch capability.Name {
166+
case "eth":
167+
if capability.Version > highestEthVersion && capability.Version <= c.ourHighestProtoVersion {
168+
highestEthVersion = capability.Version
169+
}
170+
case "snap":
171+
if capability.Version > highestSnapVersion && capability.Version <= c.ourHighestSnapProtoVersion {
172+
highestSnapVersion = capability.Version
173+
}
152174
}
153175
}
154176
c.negotiatedProtoVersion = highestEthVersion
177+
c.negotiatedSnapProtoVersion = highestSnapVersion
155178
}
156179

157180
// statusExchange performs a `Status` message exchange with the given node.
@@ -325,6 +348,15 @@ func (c *Conn) headersRequest(request *GetBlockHeaders, chain *Chain, isEth66 bo
325348
}
326349
}
327350

351+
func (c *Conn) snapRequest(msg Message, id uint64, chain *Chain) (Message, error) {
352+
defer c.SetReadDeadline(time.Time{})
353+
c.SetReadDeadline(time.Now().Add(5 * time.Second))
354+
if err := c.Write(msg); err != nil {
355+
return nil, fmt.Errorf("could not write to connection: %v", err)
356+
}
357+
return c.ReadSnap(id)
358+
}
359+
328360
// getBlockHeaders66 executes the given `GetBlockHeaders` request over the eth66 protocol.
329361
func getBlockHeaders66(chain *Chain, conn *Conn, request *GetBlockHeaders, id uint64) (BlockHeaders, error) {
330362
// write request

0 commit comments

Comments
 (0)