forked from blackmennewstyle/miningcore
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1116634
commit 800ac45
Showing
38 changed files
with
3,476 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
using System.Diagnostics; | ||
using Miningcore.Blockchain.Progpow; | ||
using Miningcore.Contracts; | ||
using Miningcore.Extensions; | ||
using Miningcore.Messaging; | ||
using Miningcore.Native; | ||
using Miningcore.Notifications.Messages; | ||
using NLog; | ||
|
||
namespace Miningcore.Crypto.Hashing.Progpow.Evrprogpow; | ||
|
||
[Identifier("evrprogpow")] | ||
public class Cache : IProgpowCache | ||
{ | ||
public Cache(int epoch) | ||
{ | ||
Epoch = epoch; | ||
LastUsed = DateTime.Now; | ||
} | ||
|
||
private IntPtr handle = IntPtr.Zero; | ||
private bool isGenerated = false; | ||
private readonly object genLock = new(); | ||
internal static IMessageBus messageBus; | ||
public int Epoch { get; } | ||
public byte[] SeedHash { get; set; } | ||
public DateTime LastUsed { get; set; } | ||
|
||
public void Dispose() | ||
{ | ||
if(handle != IntPtr.Zero) | ||
{ | ||
EvrProgpow.DestroyContext(handle); | ||
handle = IntPtr.Zero; | ||
} | ||
} | ||
|
||
public async Task GenerateAsync(ILogger logger) | ||
{ | ||
await Task.Run(() => | ||
{ | ||
lock(genLock) | ||
{ | ||
if(!isGenerated) | ||
{ | ||
|
||
var started = DateTime.Now; | ||
logger.Debug(() => $"Generating cache for epoch {Epoch}"); | ||
|
||
handle = EvrProgpow.CreateContext(Epoch); | ||
|
||
logger.Debug(() => $"Done generating cache for epoch {Epoch} after {DateTime.Now - started}"); | ||
isGenerated = true; | ||
|
||
// get the seed hash for this epoch | ||
var res = EvrProgpow.calculate_epoch_seed(Epoch); | ||
SeedHash = res.bytes; | ||
logger.Info(() => $"Seed hash for epoch {Epoch} is {SeedHash.ToHexString()}"); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
public unsafe bool Compute(ILogger logger, int blockNumber, byte[] hash, ulong nonce, out byte[] mixDigest, out byte[] result) | ||
{ | ||
Contract.RequiresNonNull(hash); | ||
|
||
var sw = Stopwatch.StartNew(); | ||
|
||
mixDigest = null; | ||
result = null; | ||
|
||
var value = new EvrProgpow.Ethash_result(); | ||
|
||
var inputHash = new EvrProgpow.Ethash_hash256(); | ||
inputHash.bytes = hash; | ||
|
||
fixed(byte* input = hash) | ||
{ | ||
value = EvrProgpow.hash(handle, blockNumber, ref inputHash, nonce); | ||
} | ||
|
||
if(value.final_hash.bytes == null) | ||
{ | ||
logger.Error(() => $"EvrProgpow.hash returned null"); | ||
return false; | ||
} | ||
|
||
mixDigest = value.mix_hash.bytes; | ||
result = value.final_hash.bytes; | ||
|
||
messageBus?.SendTelemetry("EvrProgpow", TelemetryCategory.Hash, sw.Elapsed, true); | ||
|
||
return true; | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
src/Miningcore/Crypto/Hashing/Progpow/Evrprogpow/EvrProgpowLight.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using Miningcore.Blockchain.Progpow; | ||
using NLog; | ||
|
||
namespace Miningcore.Crypto.Hashing.Progpow.Evrprogpow; | ||
|
||
[Identifier("evrprogpow")] | ||
public class EvrProgpowLight : IProgpowLight | ||
{ | ||
public void Setup(int totalCache, ulong hardForkBlock = 0) | ||
{ | ||
this.numCaches = totalCache; | ||
} | ||
|
||
private int numCaches; // Maximum number of caches to keep before eviction (only init, don't modify) | ||
private readonly object cacheLock = new(); | ||
private readonly Dictionary<int, Cache> caches = new(); | ||
private Cache future; | ||
public string AlgoName { get; } = "EvrProgpow"; | ||
|
||
public void Dispose() | ||
{ | ||
foreach(var value in caches.Values) | ||
value.Dispose(); | ||
} | ||
|
||
public async Task<IProgpowCache> GetCacheAsync(ILogger logger, int block, CancellationToken ct) | ||
{ | ||
var epoch = block / EvrmoreConstants.EpochLength; | ||
Cache result; | ||
|
||
lock(cacheLock) | ||
{ | ||
if(numCaches == 0) | ||
numCaches = 3; | ||
|
||
if(!caches.TryGetValue(epoch, out result)) | ||
{ | ||
// No cached cache, evict the oldest if the cache limit was reached | ||
while(caches.Count >= numCaches) | ||
{ | ||
var toEvict = caches.Values.OrderBy(x => x.LastUsed).First(); | ||
var key = caches.First(pair => pair.Value == toEvict).Key; | ||
var epochToEvict = toEvict.Epoch; | ||
|
||
logger.Info(() => $"Evicting cache for epoch {epochToEvict} in favour of epoch {epoch}"); | ||
toEvict.Dispose(); | ||
caches.Remove(key); | ||
} | ||
|
||
// If we have the new cache pre-generated, use that, otherwise create a new one | ||
if(future != null && future.Epoch == epoch) | ||
{ | ||
logger.Debug(() => $"Using pre-generated cache for epoch {epoch}"); | ||
|
||
result = future; | ||
future = null; | ||
} | ||
|
||
else | ||
{ | ||
logger.Info(() => $"No pre-generated cache available, creating new for epoch {epoch}"); | ||
result = new Cache(epoch); | ||
} | ||
|
||
caches[epoch] = result; | ||
} | ||
|
||
// If we used up the future cache, or need a refresh, regenerate | ||
else if(future == null || future.Epoch <= epoch) | ||
{ | ||
logger.Info(() => $"Pre-generating cache for epoch {epoch + 1}"); | ||
future = new Cache(epoch + 1); | ||
|
||
#pragma warning disable 4014 | ||
future.GenerateAsync(logger); | ||
#pragma warning restore 4014 | ||
} | ||
|
||
result.LastUsed = DateTime.Now; | ||
} | ||
|
||
// get/generate current one | ||
await result.GenerateAsync(logger); | ||
|
||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
// ReSharper disable FieldCanBeMadeReadOnly.Local | ||
// ReSharper disable MemberCanBePrivate.Local | ||
// ReSharper disable InconsistentNaming | ||
|
||
namespace Miningcore.Native; | ||
|
||
public static unsafe class EvrProgpow | ||
{ | ||
[DllImport("libevrprogpow", EntryPoint = "ethash_create_epoch_context", CallingConvention = CallingConvention.Cdecl)] | ||
public static extern IntPtr CreateContext(int epoch_number); | ||
|
||
[DllImport("libevrprogpow", EntryPoint = "ethash_destroy_epoch_context", CallingConvention = CallingConvention.Cdecl)] | ||
public static extern void DestroyContext(IntPtr context); | ||
|
||
[DllImport("libevrprogpow", EntryPoint = "hash", CallingConvention = CallingConvention.Cdecl)] | ||
public static extern Ethash_result hash(IntPtr context, int block_number, ref Ethash_hash256 header_hash, ulong nonce); | ||
|
||
[DllImport("libevrprogpow", EntryPoint = "ethash_calculate_epoch_seed", CallingConvention = CallingConvention.Cdecl)] | ||
public static extern Ethash_hash256 calculate_epoch_seed(int epoch_number); | ||
|
||
[StructLayout(LayoutKind.Explicit)] | ||
public struct Ethash_hash256 | ||
{ | ||
[FieldOffset(0)] | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] | ||
public byte[] bytes;//x32 | ||
} | ||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
public struct Ethash_result | ||
{ | ||
public Ethash_hash256 final_hash;//32 | ||
public Ethash_hash256 mix_hash;//32 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
CFLAGS += -g -Wall -c -fPIC -O2 -Wno-pointer-sign -Wno-char-subscripts -Wno-unused-variable -Wno-unused-function -Wno-strict-aliasing -Wno-discarded-qualifiers -Wno-unused-const-variable $(CPU_FLAGS) | ||
CXXFLAGS += -g -Wall -fPIC -fpermissive -O2 -Wno-char-subscripts -Wno-unused-variable -Wno-unused-function -Wno-strict-aliasing -Wno-sign-compare -std=c++11 $(CPU_FLAGS) | ||
LDFLAGS += -shared | ||
TARGET = libevrprogpow.so | ||
|
||
OBJECTS = ethash/ethash.o keccak/keccak.o keccak/keccakf800.o keccak/keccakf1600.o ethash/managed.o ethash/primes.o ethash/progpow.o | ||
|
||
all: $(TARGET) | ||
|
||
$(TARGET): $(OBJECTS) | ||
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS) | ||
|
||
.PHONY: clean | ||
|
||
clean: | ||
$(RM) $(TARGET) $(OBJECTS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. | ||
* Copyright 2018-2019 Pawel Bylica. | ||
* Licensed under the Apache License, Version 2.0. | ||
*/ | ||
|
||
#pragma once | ||
|
||
/** inline */ | ||
#if _MSC_VER || __STDC_VERSION__ | ||
#define INLINE inline | ||
#else | ||
#define INLINE | ||
#endif | ||
|
||
/** [[always_inline]] */ | ||
#if _MSC_VER | ||
#define ALWAYS_INLINE __forceinline | ||
#elif defined(__has_attribute) && __STDC_VERSION__ | ||
#if __has_attribute(always_inline) | ||
#define ALWAYS_INLINE __attribute__((always_inline)) | ||
#endif | ||
#endif | ||
#if !defined(ALWAYS_INLINE) | ||
#define ALWAYS_INLINE | ||
#endif | ||
|
||
/** [[no_sanitize()]] */ | ||
#if __clang__ | ||
#define NO_SANITIZE(sanitizer) \ | ||
__attribute__((no_sanitize(sanitizer))) | ||
#else | ||
#define NO_SANITIZE(sanitizer) | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// dllmain.cpp : Defines the entry point for the DLL application. | ||
#include "stdafx.h" | ||
|
||
BOOL APIENTRY DllMain( HMODULE hModule, | ||
DWORD ul_reason_for_call, | ||
LPVOID lpReserved | ||
) | ||
{ | ||
switch (ul_reason_for_call) | ||
{ | ||
case DLL_PROCESS_ATTACH: | ||
case DLL_THREAD_ATTACH: | ||
case DLL_THREAD_DETACH: | ||
case DLL_PROCESS_DETACH: | ||
break; | ||
} | ||
return TRUE; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm. | ||
# Copyright 2018-2019 Pawel Bylica. | ||
# Licensed under the Apache License, Version 2.0. | ||
|
||
include(GNUInstallDirs) | ||
|
||
add_library( | ||
ethash SHARED | ||
bit_manipulation.h | ||
builtins.h | ||
endianness.hpp | ||
${include_dir}/ethash/ethash.h | ||
${include_dir}/ethash/ethash.hpp | ||
ethash-internal.hpp | ||
ethash.cpp | ||
${include_dir}/ethash/hash_types.h | ||
managed.cpp | ||
kiss99.hpp | ||
primes.h | ||
primes.c | ||
${include_dir}/ethash/progpow.hpp | ||
progpow.cpp | ||
) | ||
set_property(TARGET ethash PROPERTY POSITION_INDEPENDENT_CODE ON) | ||
|
||
target_link_libraries(ethash PRIVATE keccak) | ||
target_include_directories(ethash PUBLIC $<BUILD_INTERFACE:${include_dir}>$<INSTALL_INTERFACE:include>) | ||
if(CABLE_COMPILER_GNULIKE AND NOT SANITIZE MATCHES undefined) | ||
target_compile_options(ethash PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>) | ||
endif() | ||
|
||
install( | ||
TARGETS ethash | ||
EXPORT ethashTargets | ||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
) |
Oops, something went wrong.