@@ -76,7 +76,7 @@ func forkDigestAtEpoch(state: PeerSyncNetworkState,
7676 state.forkDigests[].atEpoch (epoch, state.cfg)
7777
7878# https://github.com/ethereum/consensus-specs/blob/v1.5.0-beta.0/specs/phase0/p2p-interface.md#status
79- proc getCurrentStatus (state: PeerSyncNetworkState ): StatusMsg =
79+ proc getCurrentStatusV1 (state: PeerSyncNetworkState ): StatusMsg =
8080 let
8181 dag = state.dag
8282 wallSlot = state.getBeaconTime ().slotOrZero
@@ -166,13 +166,15 @@ proc checkStatusMsg(state: PeerSyncNetworkState, status: StatusMsg | StatusMsgV2
166166 # apparently don't use spec ZERO_HASH as of this writing
167167 if not (status.finalizedRoot in [state.genesisBlockRoot, ZERO_HASH ]):
168168 return err (" peer following different finality" )
169-
170169 ok ()
171170
172- proc handleStatus (peer: Peer ,
173- state: PeerSyncNetworkState ,
174- theirStatus: StatusMsg ): Future [bool ] {.async : (raises: [CancelledError ]).}
171+ proc handleStatusV1 (peer: Peer ,
172+ state: PeerSyncNetworkState ,
173+ theirStatus: StatusMsg ): Future [bool ] {.async : (raises: [CancelledError ]).}
175174
175+ proc handleStatusV2 (peer: Peer ,
176+ state: PeerSyncNetworkState ,
177+ theirStatus: StatusMsgV2 ): Future [bool ] {.async : (raises: [CancelledError ]).}
176178
177179{.pop .} # TODO fix p2p macro for raises
178180
@@ -195,27 +197,55 @@ p2pProtocol PeerSync(version = 1,
195197 # need a dedicated flow in libp2p that resolves the race conditions -
196198 # this needs more thinking around the ordering of events and the
197199 # given incoming flag
200+
198201 let
199- ourStatus = peer.networkState.getCurrentStatus ()
200- theirStatus = await peer.status (ourStatus, timeout = RESP_TIMEOUT_DUR )
201- ourStatusV2 = peer.networkState.getCurrentStatusV2 ()
202+ remoteFork = peer.networkState.getBeaconTime ().slotOrZero.epoch ()
203+
204+ if remoteFork >= peer.networkState.cfg.FULU_FORK_EPOCH :
205+ let
206+ ourStatus = peer.networkState.getCurrentStatusV2 ()
207+ theirStatus =
208+ await peer.statusV2 (ourStatus, timeout = RESP_TIMEOUT_DUR )
209+
210+ if theirStatus.isOk:
211+ discard await peer.handleStatusV2 (peer.networkState, theirStatus.get ())
212+ peer.updateAgent ()
213+ else :
214+ debug " Status response not received in time" ,
215+ peer, errorKind = theirStatus.error.kind
216+ await peer.disconnect (FaultOrError )
202217
203- if theirStatus.isOk:
204- discard await peer.handleStatus (peer.networkState, theirStatus.get ())
205- peer.updateAgent ()
206218 else :
207- debug " Status response not received in time" ,
208- peer, errorKind = theirStatus.error.kind
209- await peer.disconnect (FaultOrError )
210-
211- proc status (peer: Peer ,
212- theirStatus: StatusMsg ,
213- response: SingleChunkResponse [StatusMsg ])
214- {.async , libp2pProtocol (" status" , 1 ).} =
215- let ourStatus = peer.networkState.getCurrentStatus ()
216- trace " Sending status message" , peer = peer, status = ourStatus
219+ let
220+ ourStatus = peer.networkState.getCurrentStatusV1 ()
221+ theirStatus =
222+ await peer.statusV1 (ourStatus, timeout = RESP_TIMEOUT_DUR )
223+
224+ if theirStatus.isOk:
225+ discard await peer.handleStatusV1 (peer.networkState, theirStatus.get ())
226+ peer.updateAgent ()
227+ else :
228+ debug " Status response not received in time" ,
229+ peer, errorKind = theirStatus.error.kind
230+ await peer.disconnect (FaultOrError )
231+
232+ proc statusV1 (peer: Peer ,
233+ theirStatus: StatusMsg ,
234+ response: SingleChunkResponse [StatusMsg ])
235+ {.async , libp2pProtocol (" status" , 1 ).} =
236+ let ourStatus = peer.networkState.getCurrentStatusV1 ()
237+ trace " Sending status (v1)" , peer = peer, status = ourStatus
217238 await response.send (ourStatus)
218- discard await peer.handleStatus (peer.networkState, theirStatus)
239+ discard await peer.handleStatusV1 (peer.networkState, theirStatus)
240+
241+ proc statusV2 (peer: Peer ,
242+ theirStatus: StatusMsgV2 ,
243+ response: SingleChunkResponse [StatusMsgV2 ])
244+ {.async , libp2pProtocol (" status" , 2 ).} =
245+ let ourStatus = peer.networkState.getCurrentStatusV2 ()
246+ trace " Sending status (v2)" , peer = peer, status = ourStatus
247+ await response.send (ourStatus)
248+ discard await peer.handleStatusV2 (peer.networkState, theirStatus)
219249
220250 proc ping (peer: Peer , value: uint64 ): uint64
221251 {.libp2pProtocol (" ping" , 1 ).} =
@@ -251,10 +281,10 @@ proc setStatusV2Msg(peer: Peer, statusMsg: StatusMsgV2) =
251281 peer.state (PeerSync ).statusMsgV2 = statusMsg
252282 peer.state (PeerSync ).statusLastTime = Moment .now ()
253283
254- proc handleStatus (peer: Peer ,
255- state: PeerSyncNetworkState ,
256- theirStatus: StatusMsg ): Future [bool ]
257- {.async : (raises: [CancelledError ]).} =
284+ proc handleStatusV1 (peer: Peer ,
285+ state: PeerSyncNetworkState ,
286+ theirStatus: StatusMsg ): Future [bool ]
287+ {.async : (raises: [CancelledError ]).} =
258288 let
259289 res = checkStatusMsg (state, theirStatus)
260290
@@ -271,28 +301,77 @@ proc handleStatus(peer: Peer,
271301 await peer.handlePeer ()
272302 true
273303
304+ proc handleStatusV2 (peer: Peer ,
305+ state: PeerSyncNetworkState ,
306+ theirStatus: StatusMsgV2 ): Future [bool ]
307+ {.async : (raises: [CancelledError ]).} =
308+ let
309+ res = checkStatusMsg (state, theirStatus)
310+
311+ return if res.isErr ():
312+ debug " Irrelevant peer" , peer, theirStatus, err = res.error ()
313+ await peer.disconnect (IrrelevantNetwork )
314+ false
315+ else :
316+ peer.setStatusV2Msg (theirStatus)
317+
318+ if peer.connectionState == Connecting :
319+ # As soon as we get here it means that we passed handshake succesfully. So
320+ # we can add this peer to PeerPool.
321+ await peer.handlePeer ()
322+ true
323+
274324proc updateStatus * (peer: Peer ): Future [bool ] {.async : (raises: [CancelledError ]).} =
275325 # # Request `status` of remote peer ``peer``.
276326 let
277327 nstate = peer.networkState (PeerSync )
278- ourStatus = getCurrentStatus (nstate)
279- theirStatus =
280- (await peer.status (ourStatus, timeout = RESP_TIMEOUT_DUR )).valueOr:
281- return false
282328
283- await peer.handleStatus (nstate, theirStatus)
329+ if nstate.getBeaconTime ().slotOrZero.epoch () >= nstate.cfg.FULU_FORK_EPOCH :
330+ let
331+ ourStatus = getCurrentStatusV2 (nstate)
332+ theirStatus =
333+ (await peer.statusV2 (ourStatus, timeout = RESP_TIMEOUT_DUR )).valueOr:
334+ return false
335+
336+ await peer.handleStatusV2 (nstate, theirStatus)
337+ else :
338+ let
339+ ourStatus = getCurrentStatusV1 (nstate)
340+ theirStatus =
341+ (await peer.statusV1 (ourStatus, timeout = RESP_TIMEOUT_DUR )).valueOr:
342+ return false
343+
344+ await peer.handleStatusV1 (nstate, theirStatus)
284345
285346proc getHeadRoot * (peer: Peer ): Eth2Digest =
286- # # Returns head root for specific peer ``peer``.
287- peer.state (PeerSync ).statusMsg.headRoot
347+ let
348+ state = peer.networkState (PeerSync )
349+ pstate = peer.state (PeerSync )
350+ remoteFork = state.getBeaconTime ().slotOrZero.epoch ()
351+ if remoteFork >= state.cfg.FULU_FORK_EPOCH :
352+ pstate.statusMsgV2.headRoot
353+ else :
354+ pstate.statusMsg.headRoot
288355
289356proc getHeadSlot * (peer: Peer ): Slot =
290- # # Returns head slot for specific peer ``peer``.
291- peer.state (PeerSync ).statusMsg.headSlot
357+ let
358+ state = peer.networkState (PeerSync )
359+ pstate = peer.state (PeerSync )
360+ remoteFork = state.getBeaconTime ().slotOrZero.epoch ()
361+ if remoteFork >= state.cfg.FULU_FORK_EPOCH :
362+ pstate.statusMsgV2.headSlot
363+ else :
364+ pstate.statusMsg.headSlot
292365
293366proc getFinalizedEpoch * (peer: Peer ): Epoch =
294- # # Returns head slot for specific peer ``peer``.
295- peer.state (PeerSync ).statusMsg.finalizedEpoch
367+ let
368+ state = peer.networkState (PeerSync )
369+ pstate = peer.state (PeerSync )
370+ remoteFork = state.getBeaconTime ().slotOrZero.epoch ()
371+ if remoteFork >= state.cfg.FULU_FORK_EPOCH :
372+ pstate.statusMsgV2.finalizedEpoch
373+ else :
374+ pstate.statusMsg.finalizedEpoch
296375
297376proc getStatusLastTime * (peer: Peer ): chronos.Moment =
298377 # # Returns head slot for specific peer ``peer``.
0 commit comments