/// <summary> /// Requests system time from all connected peers, collects responses after 5 seconds /// and computes the median /// </summary> /// <returns>Median diff of all responses</returns> public long SyncTime() { // process responses List<long> diffs = new List<long>(); foreach (KeyValuePair<Hash, ResponseStruct> entry in collectedResponses) diffs.Add(entry.Value.diff); diffs.Add(0); collectedResponses = new ConcurrentDictionary<Hash, ResponseStruct>(); long diff = computeDiff(diffs); double display = ((double)diff) / 10000000; DateTime st = DateTime.FromFileTimeUtc(nodeState.SystemTime); DateTime nt = DateTime.FromFileTimeUtc(nodeState.NetworkTime); Print(diffs.Count + " resp; diff " + display/*.ToString("0.000")*/ + "; \tst: " + st.ToLongTimeString() + "; \tnt: " + nt.ToLongTimeString()); //send new requests //Print("start syncing with " + nodeState.ConnectedValidators.Count + " peers"); sentRequests = new ConcurrentDictionary<Hash, RequestStruct>(); foreach (Hash peer in nodeState.ConnectedValidators) { // save locally RequestStruct rs = new RequestStruct(); rs.senderTime = nodeState.SystemTime; rs.token = TNetUtils.GenerateNewToken(); sentRequests.AddOrUpdate(peer, rs, (ok, ov) => rs); // send message TimeSyncRqMsg request = new TimeSyncRqMsg(); request.senderTime = nodeState.SystemTime; byte[] message = request.Serialize(); NetworkPacket packet = new NetworkPacket(nodeConfig.PublicKey, PacketType.TPT_TIMESYNC_REQUEST, message, rs.token); networkPacketSwitch.AddToQueue(peer, packet); } return diff; }
/// <summary> /// Takes one encoded request and sends an encoded response /// </summary> /// <param name="packet"></param> private void requestHandler(NetworkPacket packet) { // unpacking request TimeSyncRqMsg request = new TimeSyncRqMsg(); request.Deserialize(packet.Data); // sending response TimeSyncRsMsg response = new TimeSyncRsMsg(); response.senderTime = request.senderTime; response.responderTime = nodeState.SystemTime; byte[] data = response.Serialize(); Hash token = packet.Token; NetworkPacket respacket = new NetworkPacket(nodeConfig.PublicKey, PacketType.TPT_TIMESYNC_RESPONSE, data, token); networkPacketSwitch.AddToQueue(packet.PublicKeySource, respacket); }