Skip to content

Commit

Permalink
v0.3.0: miner supports both, verushash v2.1 (block version 2) and v2.…
Browse files Browse the repository at this point in the history
…2 (for block version 3)
  • Loading branch information
CoinFuMasterShifu committed Jun 23, 2024
1 parent 9564f4e commit 5876be3
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 37 deletions.
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
project( 'Warthog Miner (Janushash)', ['c','cpp'],
version : '0.2.9',
version : '0.3.0',
default_options : ['warning_level=3', 'cpp_std=c++20'])


Expand Down
127 changes: 115 additions & 12 deletions src/miner/verusopt/verus_clhash_opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,16 +864,17 @@ __m128i __verusclmulwithoutreduction64alignedrepeat_sv2_1(
return acc;
}

inline __m128i _mm_load_si128_emu(const void *p) { return *(__m128i *)p; }
inline __m128i _mm_load_si128_emu(const void* p) { return *(__m128i*)p; }

inline __m128i _mm_xor_si128_emu(__m128i a, __m128i b) {
inline __m128i _mm_xor_si128_emu(__m128i a, __m128i b)
{
#ifdef _WIN32
uint64_t result[2];
result[0] = *(uint64_t *)&a ^ *(uint64_t *)&b;
result[1] = *((uint64_t *)&a + 1) ^ *((uint64_t *)&b + 1);
return *(__m128i *)result;
uint64_t result[2];
result[0] = *(uint64_t*)&a ^ *(uint64_t*)&b;
result[1] = *((uint64_t*)&a + 1) ^ *((uint64_t*)&b + 1);
return *(__m128i*)result;
#else
return a ^ b;
return a ^ b;
#endif
}

Expand Down Expand Up @@ -1145,8 +1146,6 @@ __m128i __verusclmulwithoutreduction64alignedrepeat_sv2_2(
return acc;
}



// uint64_t verusclhash_sv2_2(void *random, const unsigned char buf[64],
// uint64_t keyMask, __m128i **pMoveScratch) {
// __m128i acc = __verusclmulwithoutreduction64alignedrepeat_sv2_2(
Expand Down Expand Up @@ -1235,10 +1234,114 @@ void JanusMinerOpt::check_set_header(const std::array<uint8_t, 76>& newheader)
memcpy(hasherrefresh, hashKey, keyRefreshsize);
memset(hasherrefresh + keyRefreshsize, 0, keysize - keyRefreshsize);
}
[[nodiscard]] inline uint32_t extract_version(const std::array<uint8_t, 76>& header)
{
uint32_t res;
const auto* from { header.begin() + 68 };
memcpy(&res, from, 4);
res = hton32(res);
return res;
}
inline bool JanusMinerOpt::mine_job(MineResult& res, const CandidateBatch& j, uint32_t threshold)
{
if (extract_version(j.shared->mined.header()) == 2)
return mine_job_v2_1(res, j, threshold);
return mine_job_v2_2(res, j, threshold);
}

inline bool JanusMinerOpt::mine_job(MineResult& res, const CandidateBatch& job, const uint32_t threshold)
inline bool JanusMinerOpt::mine_job_v2_1(MineResult& res, const CandidateBatch& job, const uint32_t threshold)
{
const auto& mined { job.shared->mined };
check_set_header(mined.header());

std::array<uint32_t, 8> dummy;
std::fill(dummy.begin(), dummy.end(), 0xFFFFFFFF);
HashView dummySha256tHash(reinterpret_cast<uint8_t*>(dummy.data()));

alignas(32) Hash curHash;

u128* hashKey = (u128*)key;
uint8_t* const hasherrefresh = ((uint8_t*)hashKey) + keysize;
__m128i** const pMoveScratch = (__m128i**)(hasherrefresh + keyRefreshsize);
unsigned char* const curBuf = vh.curBuf;

uint32_t& nonce = *reinterpret_cast<uint32_t*>(curBuf + 32 + (76 - 64));

size_t offset { job.offset };
size_t len { job.len };

for (auto& span : job.resultSpans.spans) {
const auto jBound { std::min(offset + len, span.size()) };
for (size_t j = offset; j < jBound; ++j) {
nonce = hton32(span[j].nonce());
uint32_t hashStart = span[j].hashStart();
assert(hashStart != 0);
res.total += 1;
if (hashStart > threshold)
continue;
res.processed += 1;

// prepare the buffer
*(u128*)(curBuf + 32 + 16) = *(u128*)(curBuf);

// run verusclhash on the buffer
__m128i acc = __verusclmulwithoutreduction64alignedrepeat_sv2_1(
hashKey, (const __m128i*)curBuf, keyMask, pMoveScratch);
acc = _mm_xor_si128(acc, lazyLengthHash(1024, 64));
const uint64_t intermediate = precompReduction64(acc);

*(uint64_t*)(curBuf + 32 + 16) = intermediate;
*(uint64_t*)(curBuf + 32 + 16 + 8) = intermediate;

haraka512_keyed_local(curHash.data(), curBuf,
hashKey + (intermediate & keyMask16));

// refresh the key
fixupkey(pMoveScratch);

//
// now exact test
//
dummy[0] = hton32(hashStart);
auto verusFloat { CustomFloat(curHash) };
*reinterpret_cast<uint32_t*>(header.data() + 76) = nonce;
// auto sha256tFloat { CustomFloat(hashSHA256(hashSHA256(hashSHA256(header)))) };
auto sha256tFloat { CustomFloat(dummySha256tHash) };

// auto h2 = double(hashStart) / double(0xFFFFFFFF);
// spdlog::info("janushash(header): {} {} {}", sha256tFloat.to_double(), h2, threshold);
// compute janushash
constexpr auto factor { CustomFloat(0, 3006477107) };
auto janushash { verusFloat * pow(sha256tFloat, factor) };
if (janushash < job.targetV2) {
std::span<const uint8_t, 4> s((const uint8_t*)&nonce, 4);

// spdlog::info("janushash(header): {}< {}", janushash.to_double(), 1 / job.targetV2.difficulty());
// spdlog::info("header: {}", serialize_hex(header));
// spdlog::info("sha256thash: {}", serialize_hex(dummySha256tHash));
auto hs { hashSHA256(hashSHA256(hashSHA256(header))) };
// spdlog::info("SHA256(header): {}", serialize_hex(hs));
// spdlog::info("SHA256tFloat: {}", sha256tFloat.to_double());
CustomFloat hsf { hs };
// spdlog::info("SHA256tFloat2: {}", hsf.to_double());
// spdlog::info("verush(header): {}", serialize_hex(verus_hash(header)));
// spdlog::info("verusFloat: {}", verusFloat.to_double());
// spdlog::info("j {}, {}", j, span[j].nonce());
assert(curHash == verus_hash(header, false));
res.success = Verus::Success { curHash, mined.submit(s) };
return true;
}
}
len -= jBound - offset;
if (offset > span.size())
offset = 0;
else
offset -= span.size();
}
return false;
}
inline bool JanusMinerOpt::mine_job_v2_2(MineResult& res, const CandidateBatch& job, const uint32_t threshold)
{
const auto& mined { job.shared->mined };
check_set_header(mined.header());

Expand Down Expand Up @@ -1312,10 +1415,10 @@ inline bool JanusMinerOpt::mine_job(MineResult& res, const CandidateBatch& job,
// spdlog::info("SHA256tFloat: {}", sha256tFloat.to_double());
CustomFloat hsf { hs };
// spdlog::info("SHA256tFloat2: {}", hsf.to_double());
// spdlog::info("verush(header): {}", serialize_hex(verus_hash(header)));
// spdlog::info("verush(header): {}", serialize_hex(curHash));
// spdlog::info("verusFloat: {}", verusFloat.to_double());
// spdlog::info("j {}, {}", j, span[j].nonce());
assert(curHash == verus_hash(header));
assert(curHash == verus_hash(header, true));
res.success = Verus::Success { curHash, mined.submit(s) };
return true;
}
Expand Down
4 changes: 4 additions & 0 deletions src/miner/verusopt/verus_clhash_opt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ void haraka512_keyed(unsigned char* out, const unsigned char* in,
const u128* rc);
uint64_t verusclhash_sv2_1(void* random, const unsigned char buf[64],
uint64_t keyMask, __m128i** pMoveScratch);
uint64_t verusclhash_sv2_2(void* random, const unsigned char buf[64],
uint64_t keyMask, __m128i** pMoveScratch);
namespace Verus {
// class MinerOpt {
// struct Success {
Expand Down Expand Up @@ -58,6 +60,8 @@ class JanusMinerOpt {

private:
bool mine_job(MineResult& res, const CandidateBatch& j, uint32_t threshold);
bool mine_job_v2_2(MineResult& res, const CandidateBatch& j, uint32_t threshold);
bool mine_job_v2_1(MineResult& res, const CandidateBatch& j, uint32_t threshold);
void check_set_header(const std::array<uint8_t,76>&);

private:
Expand Down
1 change: 0 additions & 1 deletion src/shared/src/block/header/header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class Header : public std::array<uint8_t, HEADERBYTELENGTH> {
Header& operator=(HeaderView hv) { return *this = Header(hv); }
operator HeaderView() const { return HeaderView(data()); }
Target target(NonzeroHeight) const;
inline bool validPOW(const Hash&, NonzeroHeight) const;
inline HashView prevhash() const;
inline HashView merkleroot() const;
void set_merkleroot(std::array<uint8_t, 32>);
Expand Down
4 changes: 0 additions & 4 deletions src/shared/src/block/header/header_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ inline Target Header::target(NonzeroHeight h) const
{
return static_cast<HeaderView>(*this).target(h);
}
inline bool Header::validPOW(const Hash& h, NonzeroHeight height) const
{
return static_cast<HeaderView>(*this).validPOW(h,height);
}
inline HashView Header::prevhash() const
{
return static_cast<HeaderView>(*this).prevhash();
Expand Down
1 change: 0 additions & 1 deletion src/shared/src/block/header/view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class HeaderView : public View<80> {


inline Target target(NonzeroHeight h) const;
bool validPOW(const Hash& h, NonzeroHeight height) const;
inline uint32_t version() const;
inline HashView prevhash() const;
inline HashView merkleroot() const;
Expand Down
11 changes: 0 additions & 11 deletions src/shared/src/block/header/view_inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,6 @@
#include "difficulty.hpp"
#include "general/reader.hpp"

inline bool HeaderView::validPOW(const Hash& h, NonzeroHeight height) const
{
if (JANUSENABLED && height.value() > JANUSRETARGETSTART){
HashExponentialDigest hd; // prepare hash product of Proof of Balanced work with two algos: verus + 3xsha256
hd.digest(verus_hash({ data(), size() })); // verus hash v2.1
hd.digest(hashSHA256(h)); // triple sha
return target_v2().compatible(hd);
} else {
return target_v1().compatible(h);
}
}
inline uint32_t HeaderView::version() const
{
return readuint32(data() + offset_version);
Expand Down
8 changes: 4 additions & 4 deletions src/shared/src/crypto/verushash/verushash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,19 @@ HashKey::HashKey(HashView seed,
// spdlog::error("{}", serialize_hex(key,sizeof(key)));
}

Hash VerusHasher::finalize()
Hash VerusHasher::finalize(bool use_2_2)
{
// fill buffer to the end with the beginning of it to prevent any
// foreknowledge of bits that may contain zero
FillExtra((u128*)curBuf);

// gen new key with what is last in buffer

HashKey hk(curBuf, haraka256_port);
HashKey hk(curBuf, haraka256_port);

// run verusclhash on the buffer
uint64_t intermediate { hk.apply_verusclhash(
curBuf, verusclhash_sv2_2_port) };
curBuf, use_2_2 ? verusclhash_sv2_2_port : verusclhash_sv2_1_port) };
// fill buffer to the end with the result
FillExtra(&intermediate);

Expand All @@ -188,7 +188,7 @@ Hash VerusHasher::finalize()
constexpr uint64_t mask16 = keyMask >> 4;

haraka512_port_keyed(out.data(), curBuf,
(const u128*)hk.key_data() + (intermediate & mask16));
(const u128*)hk.key_data() + (intermediate & mask16));

return out;
};
Expand Down
6 changes: 3 additions & 3 deletions src/shared/src/crypto/verushash/verushash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class VerusHasher {
{
return write(s.data(), s.size());
}
[[nodiscard]] Hash finalize();
[[nodiscard]] Hash finalize(bool use_2_2);

private:
// data
Expand Down Expand Up @@ -63,7 +63,7 @@ class VerusHasher {
};
} // namespace Verus

[[nodiscard]] inline Hash verus_hash(std::span<const uint8_t> s) // verushash v2.1
[[nodiscard]] inline Hash verus_hash(std::span<const uint8_t> s, bool use_2_2)
{
return Verus::VerusHasher().write(s).finalize();
return Verus::VerusHasher().write(s).finalize(use_2_2);
}

0 comments on commit 5876be3

Please sign in to comment.