Пример #1
0
        public string ToString(bool withHistogram, bool showHashes)
        {
            var sb = new StringBuilder();

            using (var writer = new StringWriter(sb))
            {
                writer.WriteLine($"Longest runtimes:");
                foreach (var r in _list.OrderByDescending(i => i.Runtime).Take(10))
                {
                    writer.WriteLine($"Seed = {r.Seed}, Runtime = {r.Runtime:0.00000} s");
                }
                writer.WriteLine($"Runtime [s] Min: {Runtime.Min:0.00000}; Max: {Runtime.Max:0.00000}; Avg: {Runtime.Average:0.00000}; Stdev: {Runtime.StdDev:0.00000};");
                writer.WriteLine($"Runtime [s] 99.99th percentile: {Runtime.GetPercentile(0.9999)}");
                writer.WriteLine($"Average entropy of program output (est.): {OutputEntropy:0.00} bits");
                writer.WriteLine($"Cyclomatic complexity Min: {CyclomaticComplexity.Min}; Max: {CyclomaticComplexity.Max}; Avg: {CyclomaticComplexity.Average}; Stdev: {CyclomaticComplexity.StdDev};");
                writer.WriteLine($"Lines of code Min: {LinesOfCode.Min}; Max: {LinesOfCode.Max}; Avg: {LinesOfCode.Average}; Stdev: {LinesOfCode.StdDev};");
                writer.WriteLine($"Halstead difficulty Min: {HalsteadDifficulty.Min}; Max: {HalsteadDifficulty.Max}; Avg: {HalsteadDifficulty.Average}; Stdev: {HalsteadDifficulty.StdDev};");
                writer.WriteLine($"Matches 'SyntaxError' optimization: {SyntaxErrorValidity:P2}");
                writer.WriteLine($"'SyntaxError' optimization runtime: {SyntaxErrorRuntime:P2}");
                writer.WriteLine($"Matches 'XS': {_list.Count(ri => ri.MatchXS) / (double)_list.Count:P2}");
                if (withHistogram)
                {
                    int[] histogram = new int[(int)Math.Ceiling((Runtime.Max - Runtime.Min) / Runtime.StdDev * 10)];
                    foreach (var run in _list)
                    {
                        var index = (int)(((run.Runtime - Runtime.Min) / Runtime.StdDev * 10));
                        histogram[index]++;
                    }
                    writer.WriteLine("Runtime histogram:");
                    for (int j = 0; j < histogram.Length; ++j)
                    {
                        writer.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00000} {1}", j * Runtime.StdDev / 10 + Runtime.Min, histogram[j]));
                    }
                }
                using (var sha256 = new SHA256Managed())
                {
                    byte[] cumulative = new byte[sha256.HashSize / 8];
                    foreach (var ri in _list)
                    {
                        var hash = sha256.ComputeHash(Encoding.ASCII.GetBytes(ri.Output));
                        if (showHashes)
                        {
                            Console.WriteLine($"{ri.Seed}: {BinaryUtils.ByteArrayToString(hash)}");
                        }
                        for (int i = 0; i < hash.Length; ++i)
                        {
                            cumulative[i] ^= hash[i];
                        }
                    }
                    writer.WriteLine($"Cumulative output hash: {BinaryUtils.ByteArrayToString(cumulative)}");
                }
            }
            return(sb.ToString());
        }
Пример #2
0
        static void Main(string[] args)
        {
            string blockTemplateHex = "0707f7a4f0d605b303260816ba3f10902e1a145ac5fad3aa3af6ea44c11869dc4f853f002b2eea0000000077b206a02ca5b1d4ce6bbfdf0acac38bded34d2dcdeef95cd20cefc12f61d56109";

            if (args.Length > 0)
            {
                blockTemplateHex = args[0];
            }
            if (blockTemplateHex.Length != 152 || blockTemplateHex.Any(c => !"0123456789abcdef".Contains(c)))
            {
                Console.WriteLine("Invalid block template (152 hex characters expected).");
            }
            else
            {
                try
                {
                    var blockTemplate = BinaryUtils.StringToByteArray(blockTemplateHex);
                    var miner         = new Miner();
                    miner.Reset(blockTemplate);
                    TimeSpan        period    = TimeSpan.FromMinutes(1);
                    List <Solution> solutions = new List <Solution>(100);
                    Stopwatch       sw        = Stopwatch.StartNew();
                    while (sw.Elapsed < period)
                    {
                        var solution = miner.Solve();
                        Console.WriteLine($"Nonce = {solution.Nonce}; PoW = {BinaryUtils.ByteArrayToString(solution.ProofOfWork)}");
                        solutions.Add(solution);
                    }
                    sw.Stop();
                    var seconds = sw.Elapsed.TotalSeconds;
                    Console.WriteLine();
                    Console.WriteLine($"Solving nonces: {string.Join(", ", solutions.Select(s => s.Nonce))}");
                    Console.WriteLine();
                    Console.WriteLine($"Found {solutions.Count} solutions in {seconds} seconds. Performance = {solutions.Count / seconds} Sols./s.");
                    sw.Restart();
                    foreach (var sol in solutions)
                    {
                        if (!miner.Verify(sol))
                        {
                            Console.WriteLine($"Nonce {sol.Nonce} - verification failed");
                            return;
                        }
                    }
                    sw.Stop();
                    Console.WriteLine($"All {solutions.Count} solutions were verified in {sw.Elapsed.TotalSeconds} seconds");
                }
                catch (Exception e)
                {
                    Console.WriteLine($"ERROR: {e}");
                }
            }
        }
Пример #3
0
        private void _run()
        {
            var         factory = new ProgramFactory(_options);
            var         runner  = new ProgramRunner();
            RuntimeInfo ri;

            while ((ri = _stats.Add()) != null)
            {
                var smallSeed = Interlocked.Increment(ref _seed);
                var bigSeed   = BinaryUtils.GenerateSeed(smallSeed);
                var p         = factory.GenProgram(bigSeed);
                runner.WriteProgram(p);
                runner.ExecuteProgram(ri);
                ri.Seed = BinaryUtils.ByteArrayToString(bigSeed);
                Progress?.Invoke(this, EventArgs.Empty);
            }
        }
Пример #4
0
        public override string ToString()
        {
            var sb = new StringBuilder();

            using (var writer = new StringWriter(sb))
            {
                writer.WriteLine($"Longest runtimes:");
                for (int i = 1; i <= 10; ++i)
                {
                    var r = _list[_list.Count - i];
                    writer.WriteLine($"Seed = {r.Seed}, Runtime = {r.Runtime:0.00000} s");
                }
                writer.WriteLine($"Runtime [s] Min: {Runtime.Min:0.00000}; Max: {Runtime.Max:0.00000}; Avg: {Runtime.Average:0.00000}; Stdev: {Runtime.StdDev:0.00000};");
                writer.WriteLine($"Runtime [s] 99.99th percentile: {Runtime.GetPercentile(0.9999)}");
                writer.WriteLine($"Average entropy of program output (est.): {OutputEntropy:0.00} bits");
                writer.WriteLine($"Cyclomatic complexity Min: {CyclomaticComplexity.Min}; Max: {CyclomaticComplexity.Max}; Avg: {CyclomaticComplexity.Average}; Stdev: {CyclomaticComplexity.StdDev};");
                writer.WriteLine($"Halstead difficulty Min: {HalsteadDifficulty.Min}; Max: {HalsteadDifficulty.Max}; Avg: {HalsteadDifficulty.Average}; Stdev: {HalsteadDifficulty.StdDev};");
                int[] histogram = new int[(int)Math.Ceiling((Runtime.Max - Runtime.Min) / Runtime.StdDev * 10)];
                foreach (var run in _list)
                {
                    var index = (int)(((run.Runtime - Runtime.Min) / Runtime.StdDev * 10));
                    histogram[index]++;
                }
                Console.WriteLine("Runtime histogram:");
                for (int j = 0; j < histogram.Length; ++j)
                {
                    writer.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00000} {1}", j * Runtime.StdDev / 10 + Runtime.Min, histogram[j]));
                }
                using (var sha256 = new SHA256Managed())
                {
                    byte[] cumulative = new byte[sha256.HashSize / 8];
                    foreach (var ri in _list)
                    {
                        var hash = sha256.ComputeHash(Encoding.ASCII.GetBytes(ri.Output));
                        for (int i = 0; i < hash.Length; ++i)
                        {
                            cumulative[i] ^= hash[i];
                        }
                    }
                    writer.WriteLine($"Cumulative output hash: {BinaryUtils.ByteArrayToString(cumulative)}");
                }
            }
            return(sb.ToString());
        }
Пример #5
0
        public bool Verify(Solution sol)
        {
            for (int i = 0; i < 4; ++i)
            {
                _blockTemplate[_nonceOffset + i] = (byte)(sol.Nonce >> (8 * i));
            }
            byte[] key = _blake.ComputeHash(_blockTemplate);
            _blakeKeyed = new Blake2B256(key);
            var pow = _blakeKeyed.ComputeHash(sol.Result);

            if (!BinaryUtils.ArraysEqual(pow, sol.ProofOfWork))
            {
                Console.WriteLine("Invalid PoW");
                return(false);
            }
            var program = _factory.GenProgram(key);

            _runner.WriteProgram(program);
            var auxiliary = _blakeKeyed.ComputeHash(_runner.Buffer, 0, _runner.ProgramLength);

            if ((auxiliary[0] ^ sol.Result[0]) >= _bound)
            {
                Console.WriteLine("Invalid Auxiliary");
                return(false);
            }
            auxiliary[0] &= _clearMask;
            var ri = _runner.ExecuteProgram();

            if (!ri.Success)
            {
                throw new Exception(string.Format($"Program execution failed. Nonce value: {(sol.Nonce)}. Seed: {BinaryUtils.ByteArrayToString(key)}, {ri.Output}"));
            }
            var result = _blakeKeyed.ComputeHash(Encoding.ASCII.GetBytes(ri.Output));

            for (int i = 0; i < result.Length; ++i)
            {
                result[i] ^= auxiliary[i];
            }
            if (!BinaryUtils.ArraysEqual(sol.Result, result))
            {
                Console.WriteLine("Invalid Result");
                return(false);
            }
            return(true);
        }
Пример #6
0
        public unsafe Solution Solve()
        {
            byte[] result    = null;
            byte[] auxiliary = null;
            uint   nonce;

            fixed(byte *block = _blockTemplate)
            {
                uint *noncePtr = (uint *)(block + _nonceOffset);

                do
                {
                    (*noncePtr)++;
                    byte[] key     = _blake.ComputeHash(_blockTemplate);
                    var    program = _factory.GenProgram(key);
                    _runner.WriteProgram(program);
                    _blakeKeyed = new Blake2B256(key);
                    auxiliary   = _blakeKeyed.ComputeHash(_runner.Buffer, 0, _runner.ProgramLength);
                    var ri = _runner.ExecuteProgram();
                    if (!ri.Success)
                    {
                        throw new Exception(string.Format($"Program execution failed. Nonce value: {(*noncePtr)}. Seed: {BinaryUtils.ByteArrayToString(key)}, {ri.Output}"));
                    }
                    result = _blakeKeyed.ComputeHash(Encoding.ASCII.GetBytes(ri.Output));
                }while ((result[0] ^ auxiliary[0]) >= _bound);
                nonce = *noncePtr;
            }

            result[0] &= _clearMask;
            for (int i = 0; i < result.Length; ++i)
            {
                result[i] ^= auxiliary[i];
            }
            return(new Solution()
            {
                Nonce = nonce,
                Result = result,
                ProofOfWork = _blakeKeyed.ComputeHash(result)
            });
        }
Пример #7
0
        private void _run(CancellationToken token)
        {
            var factory = new ProgramFactory(_options);
            //var defaultRunner = new ProgramRunner();
            //var runnerNode = new ExternalProgramRunner("node", @"..\fast-eval.js");
            //var runnerXS = new ExternalProgramRunner(@"..\moddable\build\bin\win\release\xst.exe");
            var         runner = ProgramRunnerBase.FromUri(_runnerUri);
            RuntimeInfo ri;

            while (!token.IsCancellationRequested && (ri = _stats.Add()) != null)
            {
                var smallSeed = Interlocked.Increment(ref _seed);
                var bigSeed   = BinaryUtils.GenerateSeed(smallSeed);
                ri.Seed = BinaryUtils.ByteArrayToString(bigSeed);
                var p = factory.GenProgram(bigSeed);
                runner.WriteProgram(p);
                runner.ExecuteProgram(ri);
                if (!ri.Success)
                {
                    throw new InvalidProgramException();
                }

                /*bool retry = true;
                 * while (!ri.Success && retry)
                 * {
                 *  Console.WriteLine($"Error with seed {ri.Seed}");
                 *  retry = false;
                 *  runner.WriteProgram(p);
                 *  runner.ExecuteProgram(ri);
                 * }
                 * if (ri.Success)
                 * {
                 *  Console.WriteLine($"Success with seed {ri.Seed}");
                 * }
                 * else
                 * {
                 *  Console.WriteLine(ri.Output);
                 * }*/
                /*runnerXS.WriteProgram(p);
                 * var xs = runnerXS.ExecuteProgram();
                 * xs.Output = xs.Output.Replace("\r", "");
                 * if(!(ri.MatchXS = ri.Output == xs.Output))
                 * {
                 *  Console.WriteLine($"Outputs differ with seed {ri.Seed}");
                 *  var xsLines = xs.Output.Split('\n');
                 *  var riLines = ri.Output.Split('\n');
                 *  if(xsLines.Length != riLines.Length)
                 *  {
                 *      Console.WriteLine("NODE:");
                 *      Console.WriteLine(ri.Output);
                 *      Console.WriteLine("--------------------");
                 *      Console.WriteLine("XS:");
                 *      Console.WriteLine(xs.Output);
                 *      Console.WriteLine("--------------------");
                 *      throw new InvalidProgramException("Number of lines differ");
                 *  }
                 *  for(int i = 0; i < xsLines.Length; ++i)
                 *  {
                 *      if(xsLines[i] != riLines[i])
                 *      {
                 *          Console.WriteLine($"NODE: {riLines[i]}");
                 *          Console.WriteLine($"XS: {xsLines[i]}");
                 *      }
                 *  }
                 * }*/
                if (_evalTest)
                {
                    runner.WriteProgram(new SyntaxErrorProgram(p));
                    var se = new RuntimeInfo()
                    {
                        CyclomaticComplexity = -1
                    };
                    runner.ExecuteProgram(se);
                    ri.MatchSyntaxError   = (se.Output == ri.Output);
                    ri.SyntaxErrorRuntime = se.Runtime / ri.Runtime;
                }
                Progress?.Invoke(this, EventArgs.Empty);
            }
        }