Esempio n. 1
0
        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]));
                    }
                }
            }
        }
Esempio n. 2
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }