@@ -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.
101114func (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.
144161func (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.
329361func getBlockHeaders66 (chain * Chain , conn * Conn , request * GetBlockHeaders , id uint64 ) (BlockHeaders , error ) {
330362 // write request
0 commit comments