public ChainManager(BalanceLedger ledger) { balanceLedger = ledger; var files = Directory.EnumerateFiles("chains"); if (!File.Exists(@"chains\main")) { main = new Chain(); main.AddBlock(Block.Genesis); balanceLedger.ApplyDiff(balanceLedger.RewardMiner(new byte[33], Direction.Forward)); } else { foreach (var filename in files) { if (filename == @"chains\main") { main = new Chain("main"); } else { forks.Add(new Chain(filename.Split(@"\")[1])); } } } }
public void ProcessBlocks(List <Block> blocks) { var validBlocks = GetContinousValidBlocks(blocks); if (validBlocks.Count != 0) { CleanForks(); var firstBlockChain = GetFork(validBlocks[0].PreviousBlockHash); if (firstBlockChain != null) //skip every block if first valid block does not continue in any chain { var previousBlock = firstBlockChain.GetByHash(validBlocks[0].PreviousBlockHash); if (previousBlock.Height == validBlocks[0].Height - 1) { for (int i = 0; i < validBlocks.Count; i++) { var fork = GetFork(validBlocks[i].GetHash(), firstBlockChain); if (fork == null) //new block(s) :) { validBlocks = ArrayManipulator.SubArray(validBlocks.ToArray(), i, validBlocks.Count - i).ToList(); break; } firstBlockChain = fork; previousBlock = validBlocks[i]; } if (validBlocks.Count != 0) { var newBlocks = new List <Block>(); if (ValidateDifficulty(validBlocks, firstBlockChain)) { for (int i = 0; i < validBlocks.Count; i++) { if (validBlocks[i].Height > previousBlock.Height) { newBlocks.Add(validBlocks[i]); } } var virtualForkBlocks = CreateVirtualFork(firstBlockChain.GetByHash(newBlocks[0].PreviousBlockHash), newBlocks); var forkBlockHeight = virtualForkBlocks[0].Height; var reverseBlocks = main.GetBlocks(forkBlockHeight, (int)(main.Height - forkBlockHeight + 1)); //0 is common block var balanceDiff = ProcessBalanceDiff(Direction.Reverse, reverseBlocks); if (balanceDiff != null) { balanceDiff = ProcessBalanceDiff(Direction.Forward, virtualForkBlocks, balanceDiff); var writeWatch = new Stopwatch(); writeWatch.Start(); if (balanceDiff != null) //nonces and balances are ok { Chain fork; if (newBlocks[0].Height != firstBlockChain.Height + 1) //fork { fork = Fork(virtualForkBlocks); } else //block addition { fork = firstBlockChain; foreach (var block in newBlocks) { firstBlockChain.AddBlock(block); } } if (IsHeavyest(fork)) { balanceLedger.ApplyDiff(balanceDiff); if (fork != main) { SetMain(fork); } } } writeWatch.Stop(); Console.WriteLine("[ChainManager] Write time:" + writeWatch.Elapsed); } } } } } } }