Пример #1
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)
            });
        }
Пример #2
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);
            }
        }
Пример #3
0
        static int Main(string[] args)
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;

            int    threads                  = 1;
            int    count                    = 1000;
            long   seed                     = DateTime.UtcNow.Ticks;
            bool   objective                = false;
            bool   useCustomOptions         = false;
            double runtimeTarget            = 0.01; //10 ms
            double runtimeWeight            = 3e+7;
            double percentileWeight         = 500.0;
            double entropyWeight            = 1000.0;
            double linesOfCodeWeight        = 0.05;
            double halsteadDifficultyWeight = 0.5;
            double percentile               = 0.999;
            double entropyLimit             = 512;
            double evalTestWeightValidity   = 20.0;
            double evalTestWeightRuntime    = 40.0;
            bool   verbose                  = false;
            int    timeout                  = -1;
            bool   evalTest                 = false;
            bool   help                     = false;
            Uri    runnerUri                = new Uri("http://localhost:18111");
            bool   debug                    = false;
            string outfile                  = null;

            ProgramOptions customOptions = new ProgramOptions();

            customOptions.Initialize();
            Action <string> coValidate = (string s) =>
            {
                if (!useCustomOptions)
                {
                    throw new InvalidOperationException($"The option {s} must be preceded by --customOptions");
                }
            };

            OptionSet p = new OptionSet()
                          .Add("threads=", (int i) => threads         = i)
                          .Add("count=", (int i) => count             = i)
                          .Add("seed=", (long i) => seed              = i)
                          .Add("timeout=", (int i) => timeout         = 1000 * i)
                          .Add("objective", s => objective            = true)
                          .Add("customOptions", s => useCustomOptions = true)
                          .Add("verbose", s => verbose = true)
                          .Add("runtimeTarget=", (double d) => runtimeTarget         = d)
                          .Add("runtimeWeight=", (double d) => runtimeWeight         = d)
                          .Add("percentileWeight=", (double d) => percentileWeight   = d)
                          .Add("percentile=", (double d) => percentile               = d)
                          .Add("entropyWeight=", (double d) => entropyWeight         = d)
                          .Add("entropyLimit=", (double d) => entropyLimit           = d)
                          .Add("linesOfCodeWeight=", (double d) => linesOfCodeWeight = d)
                          .Add("halsteadDifficultyWeight=", (double d) => halsteadDifficultyWeight = d)
                          .Add("evalTest", s => evalTest = true)
                          .Add("evalTestWeightValidity=", (double d) => evalTestWeightValidity = d)
                          .Add("evalTestWeightRuntime=", (double d) => evalTestWeightRuntime   = d)
                          .Add("help|h", s => help          = true)
                          .Add("runnerUri=", s => runnerUri = new Uri(s))
                          .Add("debug", s => debug          = true)
                          .Add("outfile=", s => outfile     = s);


            foreach (var prop in typeof(ProgramOptions).GetProperties())
            {
                var pt = prop.PropertyType;
                if (pt.BaseType != null && pt.BaseType.IsGenericType && pt.BaseType.GetGenericTypeDefinition() == typeof(RandomTable <>))
                {
                    var itemType  = pt.BaseType.GetGenericArguments()[0];
                    var instance  = prop.GetValue(customOptions);
                    var addMethod = pt.BaseType.GetMethod("Add", new Type[] { itemType, typeof(double) });
                    foreach (var fld in itemType.GetFields(BindingFlags.Static | BindingFlags.Public))
                    {
                        string optionName = "XML_" + prop.Name + "_" + fld.Name;
                        //Console.WriteLine($"Adding option --{optionName}");
                        p.Add(optionName + "=", (double w) =>
                        {
                            coValidate(optionName);
                            addMethod.Invoke(instance, new object[] { fld.GetValue(null), w });
                        });
                    }
                }
                else if (pt == typeof(Interval))
                {
                    var    instance      = prop.GetValue(customOptions);
                    var    minProp       = pt.GetProperty(nameof(Interval.Min));
                    string optionNameMin = "XML_" + prop.Name + "_" + nameof(Interval.Min);
                    //Console.WriteLine($"Adding option --{optionNameMin}");
                    p.Add(optionNameMin + "=", (int i) =>
                    {
                        coValidate(optionNameMin);
                        minProp.SetValue(instance, i);
                    });
                    var    rangeProp       = pt.GetProperty(nameof(Interval.Span));
                    string optionNameRange = "XML_" + prop.Name + "_" + nameof(Interval.Span);
                    //Console.WriteLine($"Adding option --{optionNameRange}");
                    p.Add(optionNameRange + "=", (int i) =>
                    {
                        coValidate(optionNameRange);
                        rangeProp.SetValue(instance, i);
                    });
                }
                else
                {
                    string optionName = "XML_" + prop.Name;
                    //Console.WriteLine($"Adding option --{optionName}");
                    if (pt == typeof(int))
                    {
                        p.Add(optionName + "=", (int i) =>
                        {
                            coValidate(optionName);
                            prop.SetValue(customOptions, i);
                        });
                    }
                    if (pt == typeof(double))
                    {
                        p.Add(optionName + "=", (double d) =>
                        {
                            coValidate(optionName);
                            prop.SetValue(customOptions, d);
                        });
                    }
                    if (pt == typeof(bool))
                    {
                        p.Add(optionName + "=", (bool b) =>
                        {
                            coValidate(optionName);
                            prop.SetValue(customOptions, b);
                        });
                    }
                }
            }

            var unknown = p.Parse(args);

            if (help)
            {
                p.WriteOptionDescriptions(Console.Out);
                return(0);
            }

            /*if (unknown.Any())
             * {
             *  Console.WriteLine($"Unknown option '{unknown.First()}'");
             *  return 1;
             * }*/

            var options = useCustomOptions ? customOptions : ProgramOptions.FromXml();

            if (count == 1 && outfile != null && outfile.Length == 64 && outfile.All(c => "0123456789abcdef".Contains(c)))
            {
                var factory = new ProgramFactory(options);
                var pr      = factory.GenProgram(BinaryUtils.StringToByteArray(outfile));
                using (var file = System.IO.File.CreateText(outfile + ".js"))
                    pr.WriteTo(file);

                var runner = Run.ProgramRunnerBase.FromUri(runnerUri);
                runner.WriteProgram(pr);
                var ri = runner.ExecuteProgram();
                Console.WriteLine(ri.Output);
                Console.WriteLine($"Success = {ri.Success}");
                return(0);
            }

            var stats = MakeStats(threads, count, timeout, seed, options, objective, evalTest, runnerUri);

            if (objective)
            {
                if (stats != null && stats.IsComplete)
                {
                    var runtime1     = runtimeWeight * (stats.Runtime.Average - runtimeTarget) * (stats.Runtime.Average - runtimeTarget);
                    var runtime2     = percentileWeight * stats.Runtime.GetPercentile(percentile);
                    var entropy      = entropyWeight / Math.Max(1, stats.OutputEntropy - entropyLimit);
                    var loc          = -linesOfCodeWeight * stats.LinesOfCode.Average;
                    var halstead     = -halsteadDifficultyWeight * stats.HalsteadDifficulty.Average;
                    var evalWeakness = 0.0;

                    if (evalTest)
                    {
                        evalWeakness = evalTestWeightValidity / Math.Max(0.05, 1.0 - stats.SyntaxErrorValidity) - evalTestWeightRuntime * stats.SyntaxErrorRuntime;
                    }

                    if (verbose)
                    {
                        Console.WriteLine($"Runtime: {runtime1:0.000}");
                        Console.WriteLine($"Percentile: {runtime2:0.000}");
                        Console.WriteLine($"Entropy: {entropy:0.000}");
                        Console.WriteLine($"Lines of code: {loc:0.000}");
                        Console.WriteLine($"Halstead: {halstead:0.000}");
                        if (evalTest)
                        {
                            Console.WriteLine($"EvalWeakness: {evalWeakness:0.000}");
                        }
                    }

                    Console.WriteLine(runtime1 + runtime2 + entropy + loc + halstead + evalWeakness);
                }
                else
                {
                    Console.WriteLine(int.MaxValue);
                }
                return(0);
            }
            else if (stats != null && stats.IsComplete)
            {
                Console.WriteLine(stats.ToString(verbose, debug));
                return(0);
            }
            else
            {
                return(1);
            }
        }
Пример #4
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);
            }
        }