/// <summary> /// Insert the object in the local pipeline to be synchronized /// xmlObject is a new element inserted by an external user /// In this case this will be the node at zero level /// </summary> /// <param name="xmlObject">Serialized object im format xml</param> /// <returns></returns> internal bool AddLocal(string xmlObject) { if (string.IsNullOrEmpty(xmlObject)) { return(false); } //long Timestamp = NetworkConnection.Now.Ticks; //var Element = new Element() { Timestamp = Timestamp, XmlObject = XmlObject }; //At level 0 the timestamp will be assigned before transmission to the node in order to reduce the difference with the timestamp on the node try { var element = new Element() { XmlObject = xmlObject }; var elementPipeline = new ElementPipeline(element); elementPipeline.Levels.Add(1); //Destination level Pipeline.Add(elementPipeline); return(true); } catch { return(true); } }
/// <summary> /// Insert the objects in the local pipeline to be synchronized /// The elements come from other nodes /// </summary> /// <param name="elements">Elements come from other nodes</param> /// <param name="fromNode">From which node comes the element</param> internal ObjToNode.TimestampVector AddLocalFromNode(IEnumerable <ObjToNode> elements, Node fromNode) { ObjToNode.TimestampVector result = null; lock (Pipeline) { var count = Pipeline.Count; var thisTime = _networkConnection.Now; // Remove any objects in standby that have not received the timestamp signed by everyone lock (_standByList) _standByList.FindAll(o => (thisTime - new DateTime(o.Timestamp)).TotalSeconds >= 5).ForEach(o => _standByList.Remove(o)); foreach (var objToNode in elements) { var timePassedFromInsertion = thisTime - new DateTime(objToNode.Timestamp); UpdateStats(timePassedFromInsertion); if ((timePassedFromInsertion) <= _networkConnection.MappingNetwork.NetworkSyncTimeSpan) { if (objToNode.Level == 1) { UpdateStats(timePassedFromInsertion, true); lock (_standByList) { // You received an object from level 0 // This is an object that is just inserted, so you must certify the timestamp and send the certificate to the node that took delivery of the object. // The object must then be put on standby until the node sends all the certificates for the timestamp. if (objToNode.CheckNodeThatStartedDistributingTheObject(fromNode)) { var signature = objToNode.CreateTheSignatureForTheTimestamp(_networkConnection.MyNode, _networkConnection.Now); _standByList.Add(objToNode); if (result == null) { result = new ObjToNode.TimestampVector(); } result.Add(objToNode.ShortHash(), signature); } else { Utility.Log("security", "Check failure fromNode " + fromNode.Ip); System.Diagnostics.Debugger.Break(); } } } else { var level = objToNode.Level + 1; var elementPipeline = Pipeline.Find(x => x.Element.Timestamp == objToNode.Timestamp && x.Element.XmlObject == objToNode.XmlObject); if (elementPipeline == null) { UpdateStats(timePassedFromInsertion, true); elementPipeline = new ElementPipeline(objToNode.GetElement); Pipeline.Add(elementPipeline); } lock (elementPipeline.Levels) if (elementPipeline.Levels.Contains(level)) { elementPipeline.Levels.Add(level); } lock (elementPipeline.SendedNode) elementPipeline.SendedNode.Add(fromNode); elementPipeline.Received++; } } else { //A dishonest node has started a fork through a fake timestamp? Stats24H.ElementsArrivedOutOfTime++; _stats12H.ElementsArrivedOutOfTime++; } } if (count == Pipeline.Count) { return(result); } Pipeline.Sort(); _spooler.DataDelivery(); } return(result); }
/// <summary> /// Insert the objects in the local pipeline to be synchronized /// The objectsFromNode come from other nodes /// </summary> /// <param name="objectsFromNode">Elements come from other nodes</param> /// <param name="fromNode">From which node comes the element</param> internal ObjToNode.TimestampVector AddLocalFromNode(IEnumerable <ObjToNode> objectsFromNode, Node fromNode) { ObjToNode.TimestampVector result = null; lock (Pipeline) { var networkSyncTimeSpan = MappingNetwork.NetworkSyncTimeSpan(_networkConnection.NodeList.Count); var addList = new List <ElementPipeline>(); var thisTime = _networkConnection.Now; // Remove any objects in standby that have not received the timestamp signed by everyone lock (_standByList) _standByList.FindAll(o => (thisTime - new DateTime(o.Timestamp)).TotalSeconds >= 5).ForEach(o => _standByList.Remove(o)); foreach (var objFromNode in objectsFromNode) { var timePassedFromInsertion = thisTime - new DateTime(objFromNode.Timestamp); UpdateStats(timePassedFromInsertion); if (timePassedFromInsertion <= networkSyncTimeSpan) { if (objFromNode.Level == 1) { UpdateStats(timePassedFromInsertion, true); lock (_standByList) { // You received an object from level 0 // This is an object that is just inserted, so you must certify the timestamp and send the certificate to the node that took delivery of the object. // The object must then be put on standby until the node sends all the certificates for the timestamp. if (objFromNode.CheckNodeThatStartedDistributingTheObject(fromNode)) { var signature = objFromNode.CreateTheSignatureForTheTimestamp(_networkConnection.MyNode, _networkConnection.Now); #if DEBUG if (signature == null) { Debugger.Break(); } #endif _standByList.Add(objFromNode); if (result == null) { result = new ObjToNode.TimestampVector(); } result.Add(objFromNode.ShortHash(), signature); } else { Utility.Log("security", "check failure fromNode " + fromNode.Ip); Debugger.Break(); } } } else { var elementPipeline = Pipeline.Find(x => x.Element.Timestamp == objFromNode.Timestamp && x.Element.XmlObject == objFromNode.XmlObject); if (elementPipeline != null) { var level = objFromNode.Level + 1; lock (elementPipeline.Levels) if (!elementPipeline.Levels.Contains(level)) { elementPipeline.Levels.Add(level); } } else { UpdateStats(timePassedFromInsertion, true); var CheckSignature = objFromNode.CheckSignedTimestamp(_networkConnection, fromNode.Ip); if (CheckSignature != ObjToNode.CheckSignedTimestampResult.Ok) { Debugger.Break(); } else { #if DEBUG var duplicate = Pipeline.Find(x => x.Element.XmlObject == objFromNode.XmlObject); if (duplicate != null) { Debugger.Break(); } #endif elementPipeline = new ElementPipeline(objFromNode); addList.Add(elementPipeline); } } if (elementPipeline != null) { lock (elementPipeline.ExcludeNodes) elementPipeline.ExcludeNodes.Add(fromNode); elementPipeline.Received++; } } } else { //A dishonest node has started a fork through a fake timestamp? Stats24H.ElementsArrivedOutOfTime++; _stats12H.ElementsArrivedOutOfTime++; } } Pipeline.Add(addList); } return(result); }