public bool IsBlockchainValid(Block[] chain)
        {
            Block lastBlock = chain.LastOrDefault();

            Block[] chainWithoutGenesisBlock = chain.Skip(1).ToArray();

            bool hasMatchByHash = chainWithoutGenesisBlock.All(block => block.PreviousHash == hashCalculator.CalculateBlockHash(lastBlock));

            bool hasMatchByProof = chainWithoutGenesisBlock.All(block => proofValidator.IsProofValid(lastBlock.Proof, block.Proof));

            return(hasMatchByHash && hasMatchByProof);
        }
        public int GetProofOfWork(int lastProof)
        {
            int[] workload = Enumerable.Range(1, 8).Select(i => Int32.MaxValue / 8 / i).ToArray();

            Task <int>[] workTasks = workload.Select(work => Task.Run(() =>
            {
                int proof = work;
                while (!proofValidator.IsProofValid(lastProof, proof))
                {
                    proof += 1;
                }
                return(proof);
            })).ToArray();

            int taskIndex = Task.WaitAny(workTasks);

            int result = workTasks[taskIndex].Result;

            return(result);
        }