Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ endif()
if (TOOL_MOCKER)
add_compile_definitions(TOOL_MOCKER)
endif()
if (TOOL_TRACE_MEMORY OR TOOL_MOCKER)
add_compile_definitions(TOOLS_ENABLE)
endif()


################################################################################
Expand Down
7 changes: 7 additions & 0 deletions PARAMETERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,10 @@ N/A : No default value is set.
|---------|--------|--------------|-------------|---------|
| `--sm_wallet` | ✅ | N/A | Assign a wallet with a coin. | `--sm_wallet=COIN:WALLET` |
| `--sm_pool` | ✅ | N/A | Assign a pool with a coin. | `--sm_pool=COIN@POOL_URL:POOL_PORT` |


## Tools Developer

| Parameter | Optional | Default Value | Description | Example |
|---------|--------|--------------|-------------|---------|
| `--tool_mocker_resolver_count` | ✅ | 8 | Defines the number of fake devices that will mine / create fake latency. | `--tool_mocker_resolver_count=8` |
1 change: 0 additions & 1 deletion sources/algo/dag_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ namespace algo
uint64_t period{ 0ull };
HashContext<algo::hash512> lightCache{};
HashContext<algo::hash1024> dagCache{};
algo::hash256 originalSeedCache{};
algo::hash512 hashedSeedCache{};
};
}
14 changes: 12 additions & 2 deletions sources/algo/ethash/cuda/memory.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ bool ethashInitMemory(
}

////////////////////////////////////////////////////////////////////////////
CU_ALLOC(&params.seedCache, algo::LEN_HASH_512);
if (true == buildLightCacheOnGPU)
{
CU_ALLOC(&params.seedCache, algo::LEN_HASH_512);
}

////////////////////////////////////////////////////////////////////////////
CU_ALLOC(&params.lightCache, context.lightCache.size);
CU_ALLOC(&params.dagCache, context.dagCache.size);
CU_ALLOC_HOST(&params.resultCache, sizeof(algo::ethash::Result) * 2u);
Expand All @@ -47,10 +52,15 @@ bool ethashInitMemory(
params.resultCache[1].nonces[i] = 0ull;
}

////////////////////////////////////////////////////////////////////////////
if (true == buildLightCacheOnGPU)
{
IS_NULL(params.seedCache);
}

////////////////////////////////////////////////////////////////////////////
IS_NULL(params.lightCache);
IS_NULL(params.dagCache);
IS_NULL(params.seedCache);
IS_NULL(params.resultCache);

////////////////////////////////////////////////////////////////////////////
Expand Down
155 changes: 110 additions & 45 deletions sources/algo/ethash/ethash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@
#include <common/log/log.hpp>


int32_t algo::ethash::findEpoch(
algo::ethash::ContextGenerator& algo::ethash::ContextGenerator::instance()
{
static algo::ethash::ContextGenerator handler{};
return handler;
}


int32_t algo::ethash::ContextGenerator::findEpoch(
algo::hash256 const& seedHash,
uint32_t const maxEpoch)
uint32_t const maxEpoch) const
{
////////////////////////////////////////////////////////////////////////////
static thread_local int32_t cachedEpochNumber{ 0 };
Expand Down Expand Up @@ -56,29 +63,65 @@ int32_t algo::ethash::findEpoch(
}


void algo::ethash::freeDagContext(algo::DagContext& context)
void algo::ethash::ContextGenerator::free(algo::ALGORITHM const algorithm)
{
////////////////////////////////////////////////////////////////////////////
SAFE_DELETE_ARRAY(context.data);
context.lightCache.hash = nullptr;
UNIQUE_LOCK(mtxContexts);

////////////////////////////////////////////////////////////////////////////
algo::ethash::ContextGenerator::DagContextShare& contextShare{ getContext(algorithm) };

////////////////////////////////////////////////////////////////////////////
--contextShare.count;
if (0u == contextShare.count)
{
SAFE_DELETE_ARRAY(contextShare.context.data);
contextShare.context.lightCache.hash = nullptr;
}
}


algo::ethash::ContextGenerator::DagContextShare& algo::ethash::ContextGenerator::getContext(
algo::ALGORITHM const algorithm)
{
return contexts[algorithm];
}


void algo::ethash::initializeDagContext(
void algo::ethash::ContextGenerator::build(
algo::ALGORITHM const algorithm,
algo::DagContext& context,
uint64_t const currentEpoch,
uint32_t const maxEpoch,
uint64_t const dagCountItemsGrowth,
uint64_t const dagCountItemsInit,
uint32_t const lightCacheCountItemsGrowth,
uint32_t const lightCacheCountItemsInit)
uint32_t const lightCacheCountItemsInit,
bool const buildOnCPU)
{
////////////////////////////////////////////////////////////////////////////
context.epoch = castU32(currentEpoch);
if ( castU32(context.epoch) > maxEpoch
UNIQUE_LOCK(mtxContexts);

///////////////////////////////////////////////////////////////////////////
algo::ethash::ContextGenerator::DagContextShare& contextShare{ getContext(algorithm) };
algo::DagContext& localDagContext{ contextShare.context };

////////////////////////////////////////////////////////////////////////////
++contextShare.count;

////////////////////////////////////////////////////////////////////////////
if (localDagContext.epoch == cast32(currentEpoch))
{
copyContext(context, algorithm);
return;
}

////////////////////////////////////////////////////////////////////////////
localDagContext.epoch = castU32(currentEpoch);
if ( castU32(localDagContext.epoch) > maxEpoch
&& algo::ethash::EIP1057_MAX_EPOCH_NUMER != maxEpoch)
{
logErr() << "context.epoch: " << context.epoch << " | maxEpoch: " << maxEpoch;
logErr() << "context.epoch: " << localDagContext.epoch << " | maxEpoch: " << maxEpoch;
return;
}

Expand All @@ -94,83 +137,105 @@ void algo::ethash::initializeDagContext(
}

////////////////////////////////////////////////////////////////////////////
uint64_t lightCacheNumItemsUpperBound { castU64(epochEIP) };
uint64_t lightCacheNumItemsUpperBound{ castU64(epochEIP) };
lightCacheNumItemsUpperBound *= lightCacheCountItemsGrowth;
lightCacheNumItemsUpperBound += lightCacheCountItemsInit;
context.lightCache.numberItem = algo::largestPrime(lightCacheNumItemsUpperBound);
context.lightCache.size = context.lightCache.numberItem * algo::LEN_HASH_512;
localDagContext.lightCache.numberItem = algo::largestPrime(lightCacheNumItemsUpperBound);
localDagContext.lightCache.size = localDagContext.lightCache.numberItem * algo::LEN_HASH_512;

////////////////////////////////////////////////////////////////////////////
uint64_t numberItemUpperBound{ castU64(epochEIP) };
numberItemUpperBound *= dagCountItemsGrowth;
numberItemUpperBound += dagCountItemsInit;
context.dagCache.numberItem = algo::largestPrime(numberItemUpperBound);
context.dagCache.size = context.dagCache.numberItem * algo::LEN_HASH_1024;
localDagContext.dagCache.numberItem = algo::largestPrime(numberItemUpperBound);
localDagContext.dagCache.size = localDagContext.dagCache.numberItem * algo::LEN_HASH_1024;

////////////////////////////////////////////////////////////////////////////
algo::hash256 seed{};
for (int32_t i{ 0 }; i < context.epoch; ++i)
for (int32_t i{ 0 }; i < localDagContext.epoch; ++i)
{
seed = algo::keccak(seed);
}
algo::copyHash(context.originalSeedCache, seed);
}


void algo::ethash::buildLightCache(
algo::DagContext& context,
bool const buildOnCPU)
{
////////////////////////////////////////////////////////////////////////////
algo::hash512 item
{
algo::keccak<algo::hash512, algo::hash256>(context.originalSeedCache)
};
algo::hash512 seedHash{ algo::keccak<algo::hash512, algo::hash256>(seed) };
algo::copyHash(localDagContext.hashedSeedCache, seedHash);

////////////////////////////////////////////////////////////////////////////
if (false == buildOnCPU)
if (true == buildOnCPU)
{
algo::copyHash(context.hashedSeedCache, item);
return;
buildLightCache(algorithm);
}

////////////////////////////////////////////////////////////////////////////
size_t const dataLength{ algo::LEN_HASH_512 + context.lightCache.size };
context.data = NEW_ARRAY(char, dataLength);
std::memset(context.data, 0, sizeof(char) * dataLength);
if (nullptr == context.data)
copyContext(context, algorithm);
}


void algo::ethash::ContextGenerator::buildLightCache(
algo::ALGORITHM const algorithm)
{
////////////////////////////////////////////////////////////////////////////
algo::ethash::ContextGenerator::DagContextShare& contextShare{ getContext(algorithm) };
algo::DagContext& localDagContext{ contextShare.context };

////////////////////////////////////////////////////////////////////////////
algo::hash512 item{ localDagContext.hashedSeedCache };
size_t const dataLength{ algo::LEN_HASH_512 + localDagContext.lightCache.size };
localDagContext.data = NEW_ARRAY(char, dataLength);
std::memset(localDagContext.data, 0, sizeof(char) * dataLength);
if (nullptr == localDagContext.data)
{
logErr() << "Cannot alloc context data";
return;
}
context.lightCache.hash = castPtrHash512(context.data + algo::LEN_HASH_512);
context.lightCache.hash[0] = item;
localDagContext.lightCache.hash = castPtrHash512(localDagContext.data + algo::LEN_HASH_512);

////////////////////////////////////////////////////////////////////////////
logInfo() << "Building light cache on CPU";
common::ChronoGuard chrono{ "Built light cache", common::CHRONO_UNIT::MS };
common::ChronoGuard chrono{ "Built light cache on CPU", common::CHRONO_UNIT::MS };

////////////////////////////////////////////////////////////////////////////
for (uint64_t i{ 1ull }; i < context.lightCache.numberItem; ++i)
for (uint64_t i{ 0ull }; i < localDagContext.lightCache.numberItem; ++i)
{
localDagContext.lightCache.hash[i] = item;
item = algo::keccak(item);
context.lightCache.hash[i] = item;
}

////////////////////////////////////////////////////////////////////////////
uint32_t const numberItemu32 { castU32(context.lightCache.numberItem) };
uint32_t const numberItemu32{ castU32(localDagContext.lightCache.numberItem) };
for (uint64_t round{ 0ull }; round < algo::ethash::LIGHT_CACHE_ROUNDS; ++round)
{
for (uint64_t i{ 0ull }; i < context.lightCache.numberItem; ++i)
for (uint64_t i{ 0ull }; i < localDagContext.lightCache.numberItem; ++i)
{
uint32_t const fi{ context.lightCache.hash[i].word32[0] % numberItemu32 };
uint32_t const fi{ localDagContext.lightCache.hash[i].word32[0] % numberItemu32 };
uint32_t const si{ (numberItemu32 + (castU32(i) - 1u)) % numberItemu32 };

algo::hash512 const& firstCache{ context.lightCache.hash[fi] };
algo::hash512 const& secondCache{ context.lightCache.hash[si] };
algo::hash512 const& firstCache{ localDagContext.lightCache.hash[fi] };
algo::hash512 const& secondCache{ localDagContext.lightCache.hash[si] };

algo::hash512 const xored = algo::hashXor(firstCache, secondCache);
context.lightCache.hash[i] = algo::keccak(xored);
localDagContext.lightCache.hash[i] = algo::keccak(xored);
}
}
}


void algo::ethash::ContextGenerator::copyContext(
algo::DagContext& context,
algo::ALGORITHM const algorithm)
{
////////////////////////////////////////////////////////////////////////////
algo::ethash::ContextGenerator::DagContextShare& contextShare{ getContext(algorithm) };
algo::DagContext& localDagContext{ contextShare.context };

context.epoch = localDagContext.epoch;
context.lightCache.numberItem = localDagContext.lightCache.numberItem;
context.lightCache.size = localDagContext.lightCache.size;
context.dagCache.numberItem = localDagContext.dagCache.numberItem;
context.dagCache.size = localDagContext.dagCache.size;
context.data = localDagContext.data;
context.lightCache.hash = localDagContext.lightCache.hash;

algo::copyHash(context.hashedSeedCache, localDagContext.hashedSeedCache);
}
47 changes: 35 additions & 12 deletions sources/algo/ethash/ethash.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#pragma once

#if !defined(__LIB_CUDA)
#include <boost/thread.hpp>

#include <algo/hash.hpp>
#include <algo/algo_type.hpp>
#include <algo/dag_context.hpp>
#endif

Expand Down Expand Up @@ -32,18 +35,38 @@ namespace algo
constexpr uint64_t DAG_COUNT_ITEMS_GROWTH{ algo::ethash::DAG_GROWTH / algo::LEN_HASH_1024 };

#if !defined(__LIB_CUDA)
int32_t findEpoch(algo::hash256 const& seedHash,
uint32_t const maxEpoch);
void initializeDagContext(algo::DagContext& context,
uint64_t const currentEpoch,
uint32_t const maxEpoch,
uint64_t const dagCountItemsGrowth,
uint64_t const dagCountItemsInit,
uint32_t const lightCacheCountItemsGrowth,
uint32_t const lightCacheCountItemsInit);
void freeDagContext(algo::DagContext& context);
void buildLightCache(algo::DagContext& context,
bool const buildOnCPU);
struct ContextGenerator
{
public:
static ContextGenerator& instance();
int32_t findEpoch(algo::hash256 const& seedHash,
uint32_t const maxEpoch) const;
void free(algo::ALGORITHM const algorithm);
void build(algo::ALGORITHM const algorithm,
algo::DagContext& context,
uint64_t const currentEpoch,
uint32_t const maxEpoch,
uint64_t const dagCountItemsGrowth,
uint64_t const dagCountItemsInit,
uint32_t const lightCacheCountItemsGrowth,
uint32_t const lightCacheCountItemsInit,
bool const buildOnCPU);

private:
struct DagContextShare
{
uint32_t count{ 0u };
algo::DagContext context;
};
boost::mutex mtxContexts{};
std::map<algo::ALGORITHM, DagContextShare> contexts{};

ContextGenerator() = default;
DagContextShare& getContext(algo::ALGORITHM const algorithm);
void buildLightCache(algo::ALGORITHM const algorithm);
void copyContext(algo::DagContext& context,
algo::ALGORITHM const algorithm);
};
#endif
}
}
8 changes: 4 additions & 4 deletions sources/algo/ethash/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ namespace algo
struct ResultShare
{
std::string jobId{};
bool found { false };
uint32_t extraNonceSize { 0u };
uint32_t count { 0u };
uint64_t nonces[algo::ethash::MAX_RESULT] { 0ull, 0ull, 0ull, 0ull };
bool found{ false };
uint32_t extraNonceSize{ 0u };
uint32_t count{ 0u };
uint64_t nonces[algo::ethash::MAX_RESULT]{ 0ull, 0ull, 0ull, 0ull };
};
#endif
}
Expand Down
Loading
Loading