private async Task HandlePeerStatus(string peerId, PeeringStatus peerPeeringStatus, Root headRoot, BeaconState beaconState) { // if not valid, "immediately disconnect from one another following the handshake" bool isValidPeer = await IsValidPeerStatus(peerId, peerPeeringStatus, headRoot, beaconState) .ConfigureAwait(false); if (!isValidPeer) { await _networkPeering.DisconnectPeerAsync(peerId).ConfigureAwait(false); return; } // check if we should request blocks var isPeerAhead = IsPeerAhead(peerPeeringStatus, beaconState); if (isPeerAhead) { // In theory, our chain since finalized checkpoint could be wrong // However it may be more efficient to check if our head is correct and sync from there, // or use the step option to sample blocks and find where we diverge. Slot finalizedSlot = _beaconChainUtility.ComputeStartSlotOfEpoch(beaconState.FinalizedCheckpoint.Epoch); if (_logger.IsInfo()) { Log.RequestingBlocksFromAheadPeer(_logger, peerId, finalizedSlot, peerPeeringStatus.HeadRoot, peerPeeringStatus.HeadSlot, null); } // TODO: Need more sophistication, like Eth1; as peers are discovered, just put into a pool, // then, when need for sync determined, select the best peer(s) to use. await _networkPeering.RequestBlocksAsync(peerId, peerPeeringStatus.HeadRoot, finalizedSlot, peerPeeringStatus.HeadSlot); } else { if (_logger.IsDebug()) { LogDebug.PeerBehind(_logger, peerId, peerPeeringStatus.FinalizedEpoch, peerPeeringStatus.HeadRoot, peerPeeringStatus.HeadSlot, null); } } }