private static void TestChain() { var genesis = Block.GenerateGenesis(); // save genesis to blockStore // save genesis to Chain var chain = new Chain(genesis.Header); var newBlock = new Block(chain.Last.Header.GetHash(), chain.Count, DateTime.UtcNow.ToUnixTimeSeconds()) { Data = "This is some test data!" }; chain.AddLast(newBlock.Header); var newBlock2 = new Block(chain.Last.Header.GetHash(), chain.Count, DateTime.UtcNow.ToUnixTimeSeconds()) { Data = "More test data!" }; chain.AddLast(newBlock2.Header); var newBlock3 = new Block(chain.Last.Header.GetHash(), chain.Count, DateTime.UtcNow.ToUnixTimeSeconds()) { Data = "Even more test data!" }; chain.AddLast(newBlock3.Header); foreach (var blockHeader in chain.Enumerate()) { } }
private static Chain TryToOptimizeJ21(ExperimentInfo experimentInfo) { var(firstBox, secondBox, asteriskBox) = SplitToBoxes( experimentInfo.J21, detail => detail.OnSecond.Time.B <= detail.OnFirst.Time.A, detail => detail.OnFirst.Time.B <= detail.OnSecond.Time.A); var sortedFirstBox = firstBox .OrderBy(detail => detail.OnSecond.Time.A) .ToList(); var sortedSecondBox = secondBox .OrderBy(detail => detail.OnFirst.Time.A) .Reverse() .ToList(); var firstChain = GetChainFromBox( sortedFirstBox, (previousDetail, currentDetail) => previousDetail.OnSecond.Time.B > currentDetail.OnSecond.Time.A); var secondChain = GetChainFromBox( sortedSecondBox, (previousDetail, currentDetail) => previousDetail.OnFirst.Time.A < currentDetail.OnFirst.Time.B); if (!asteriskBox.Any()) { return(new Chain(firstChain.Concat(secondChain))); } if (asteriskBox.Count() == 1) { return(new Chain(firstChain.Append(asteriskBox.First()).Concat(secondChain))); } //find conflict borders var minAOnFirst = asteriskBox.Min(detail => detail.OnFirst.Time.A); var minAOnSecond = asteriskBox.Min(detail => detail.OnSecond.Time.A); var resultChain = new Chain(); var jConflict = new Conflict(); foreach (var chainElement in firstChain) { if (chainElement.Type == ChainType.Conflict) { var conflict = chainElement as Conflict; if (conflict.Details.Values.Max(detail => detail.OnSecond.Time.B) > minAOnSecond) { //we find a border of conflict var chainNode = firstChain.Find(chainElement); while (chainNode != null) { var nodeValue = chainNode.Value; jConflict.AddDetails(nodeValue); chainNode = chainNode.Next; } break; } resultChain.AddLast(chainElement); } else { var detail = chainElement as LaboriousDetail; if (detail.OnSecond.Time.B > minAOnSecond) { //we find a border of conflict var chainNode = firstChain.Find(chainElement); while (chainNode != null) { jConflict.AddDetails(chainNode.Value); chainNode = chainNode.Next; } break; } resultChain.AddLast(chainElement); } } jConflict.Details.AddRange(asteriskBox.Select(x => new KeyValuePair <int, LaboriousDetail>(x.Number, x))); foreach (var chainElement in secondChain) { if (chainElement.Type == ChainType.Conflict) { var conflict = chainElement as Conflict; if (conflict.Details.Values.Max(detail => detail.OnFirst.Time.B) > minAOnFirst) { jConflict.Details.AddRange(conflict.Details); } else { resultChain.AddLast(jConflict); jConflict = null; var chainNode = secondChain.Find(chainElement); while (chainNode != null) { resultChain.AddLast(chainNode.Value); chainNode = chainNode.Next; } break; } } else { var detail = chainElement as LaboriousDetail; if (detail.OnFirst.Time.B > minAOnFirst) { jConflict.Details.Add(detail.Number, detail); } else { resultChain.AddLast(jConflict); jConflict = null; var chainNode = secondChain.Find(chainElement); while (chainNode != null) { resultChain.AddLast(chainNode.Value); chainNode = chainNode.Next; } break; } } } if (jConflict != null) { resultChain.AddLast(jConflict); } return(resultChain); }
private static Chain GetChainFromBox( IReadOnlyCollection <LaboriousDetail> sortedBox, Func <LaboriousDetail, LaboriousDetail, bool> conflictPredicate) { if (sortedBox.Count == 1) { return(new Chain(sortedBox)); } var chain = new Chain(); foreach (var detailFromSortedBox in sortedBox) { //chain have elements if (chain.Any()) { //last element from chain var lastElement = chain.Last; if (lastElement.Value.Type == ChainType.Conflict) { var conflict = lastElement.Value as Conflict; var isConflict = conflict.Details.Values.Any(detail => conflictPredicate.Invoke(detail, detailFromSortedBox)); if (isConflict) { conflict.Details.Add(detailFromSortedBox.Number, detailFromSortedBox); } else { chain.AddLast(detailFromSortedBox); } } else { var lastDetail = lastElement.Value as LaboriousDetail; if (conflictPredicate.Invoke(lastDetail, detailFromSortedBox)) { //it's conflict var conflict = new Conflict(); conflict.Details.Add(lastDetail.Number, lastDetail); conflict.Details.Add(detailFromSortedBox.Number, detailFromSortedBox); chain.RemoveLast(); chain.AddLast(conflict); } else { chain.AddLast(detailFromSortedBox); } } } //chain doesn't have elements else { chain.AddLast(detailFromSortedBox); } } return(chain); }
public void BasicChainTest() { var time = DateTime.UtcNow.ToUnixTimeSeconds(); var genesisBlock = Block.GenerateGenesis(); // save genesis to blockStore // save genesis to Chain var chain = new Chain(genesisBlock.Header); var firstBlock = new Block(chain.Last.Header.GetHash(), chain.Count, time + 1000) { Data = "Some Test Data!" }; chain.AddLast(firstBlock.Header); var secondBlock = new Block(chain.Last.Header.GetHash(), chain.Count, time + 2000) { Data = "More Test Data!" }; chain.AddLast(secondBlock.Header); var thirdBlock = new Block(chain.Last.Header.GetHash(), chain.Count, time + 3000) { Data = "Even More Test Data!" }; chain.AddLast(thirdBlock.Header); Assert.IsTrue(chain.Count == 4); Assert.AreNotEqual(chain.Genesis, chain.Last); // Genesis var genesis = chain[0]; Assert.AreEqual(genesisBlock.Header, genesis.Header); Assert.AreEqual(genesisBlock.Header.GetHash(), genesis.BlockHash); Assert.AreEqual(genesis.Header.BlockTimestamp, time); Assert.AreEqual(genesis.Header.PreviousHash, ZeroHash); Assert.AreEqual(genesis.Header.DataHash, EmptyDataHash); // First var first = chain[1]; Assert.AreEqual(firstBlock.Header, first.Header); Assert.AreEqual(firstBlock.Header.GetHash(), first.BlockHash); Assert.AreEqual(first.Header.BlockTimestamp, time + 1000); Assert.AreEqual(first.Header.PreviousHash, firstBlock.Header.PreviousHash); Assert.AreEqual(first.Header.DataHash, firstBlock.Header.DataHash); Assert.AreNotEqual(first.Header.DataHash, EmptyDataHash); // Second var second = chain[2]; Assert.AreEqual(secondBlock.Header, second.Header); Assert.AreEqual(secondBlock.Header.GetHash(), second.BlockHash); Assert.AreEqual(second.Header.BlockTimestamp, time + 2000); Assert.AreEqual(second.Header.PreviousHash, secondBlock.Header.PreviousHash); Assert.AreEqual(second.Header.DataHash, secondBlock.Header.DataHash); Assert.AreNotEqual(second.Header.DataHash, EmptyDataHash); // Thrid var third = chain[3]; Assert.AreEqual(thirdBlock.Header, third.Header); Assert.AreEqual(thirdBlock.Header.GetHash(), third.BlockHash); Assert.AreEqual(third.Header.BlockTimestamp, time + 3000); Assert.AreEqual(third.Header.PreviousHash, thirdBlock.Header.PreviousHash); Assert.AreEqual(third.Header.DataHash, thirdBlock.Header.DataHash); Assert.AreNotEqual(third.Header.DataHash, EmptyDataHash); }