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) }); }
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); } }