Use template parameters to statically initialise Equihash
This commit is contained in:
parent
39f5cb35f9
commit
e95747288a
|
@ -19,31 +19,18 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
void validate_params(int n, int k)
|
||||
{
|
||||
if (k>=n) {
|
||||
std::cerr << "n must be larger than k\n";
|
||||
throw invalid_params();
|
||||
}
|
||||
if (n % 8 != 0) {
|
||||
std::cerr << "Parameters must satisfy n = 0 mod 8\n";
|
||||
throw invalid_params();
|
||||
}
|
||||
if ((n/(k+1)) % 8 != 0) {
|
||||
std::cerr << "Parameters must satisfy n/(k+1) = 0 mod 8\n";
|
||||
throw invalid_params();
|
||||
}
|
||||
}
|
||||
|
||||
int Equihash::InitialiseState(eh_HashState& base_state)
|
||||
template<unsigned int N, unsigned int K>
|
||||
int Equihash<N,K>::InitialiseState(eh_HashState& base_state)
|
||||
{
|
||||
unsigned int n = N;
|
||||
unsigned int k = K;
|
||||
unsigned char personalization[crypto_generichash_blake2b_PERSONALBYTES] = {};
|
||||
memcpy(personalization, "ZcashPOW", 8);
|
||||
memcpy(personalization+8, &n, 4);
|
||||
memcpy(personalization+12, &k, 4);
|
||||
return crypto_generichash_blake2b_init_salt_personal(&base_state,
|
||||
NULL, 0, // No key.
|
||||
n/8,
|
||||
N/8,
|
||||
NULL, // No salt.
|
||||
personalization);
|
||||
}
|
||||
|
@ -238,27 +225,21 @@ eh_trunc* TruncatedStepRow::GetPartialSolution(eh_index soln_size) const
|
|||
return p;
|
||||
}
|
||||
|
||||
Equihash::Equihash(unsigned int n, unsigned int k) :
|
||||
n(n), k(k)
|
||||
template<unsigned int N, unsigned int K>
|
||||
std::set<std::vector<eh_index>> Equihash<N,K>::BasicSolve(const eh_HashState& base_state)
|
||||
{
|
||||
validate_params(n, k);
|
||||
}
|
||||
|
||||
std::set<std::vector<eh_index>> Equihash::BasicSolve(const eh_HashState& base_state)
|
||||
{
|
||||
assert(CollisionBitLength() + 1 < 8*sizeof(eh_index));
|
||||
eh_index init_size { 1 << (CollisionBitLength() + 1) };
|
||||
eh_index init_size { 1 << (CollisionBitLength + 1) };
|
||||
|
||||
// 1) Generate first list
|
||||
LogPrint("pow", "Generating first list\n");
|
||||
std::vector<FullStepRow> X;
|
||||
X.reserve(init_size);
|
||||
for (eh_index i = 0; i < init_size; i++) {
|
||||
X.emplace_back(n, base_state, i);
|
||||
X.emplace_back(N, base_state, i);
|
||||
}
|
||||
|
||||
// 3) Repeat step 2 until 2n/(k+1) bits remain
|
||||
for (int r = 1; r < k && X.size() > 0; r++) {
|
||||
for (int r = 1; r < K && X.size() > 0; r++) {
|
||||
LogPrint("pow", "Round %d:\n", r);
|
||||
// 2a) Sort the list
|
||||
LogPrint("pow", "- Sorting list\n");
|
||||
|
@ -272,7 +253,7 @@ std::set<std::vector<eh_index>> Equihash::BasicSolve(const eh_HashState& base_st
|
|||
// 2b) Find next set of unordered pairs with collisions on the next n/(k+1) bits
|
||||
int j = 1;
|
||||
while (i+j < X.size() &&
|
||||
HasCollision(X[i], X[i+j], CollisionByteLength())) {
|
||||
HasCollision(X[i], X[i+j], CollisionByteLength)) {
|
||||
j++;
|
||||
}
|
||||
|
||||
|
@ -281,7 +262,7 @@ std::set<std::vector<eh_index>> Equihash::BasicSolve(const eh_HashState& base_st
|
|||
for (int m = l + 1; m < j; m++) {
|
||||
if (DistinctIndices(X[i+l], X[i+m])) {
|
||||
Xc.push_back(X[i+l] ^ X[i+m]);
|
||||
Xc.back().TrimHash(CollisionByteLength());
|
||||
Xc.back().TrimHash(CollisionByteLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -383,14 +364,14 @@ void CollideBranches(std::vector<FullStepRow>& X, const unsigned int clen, const
|
|||
}
|
||||
}
|
||||
|
||||
std::set<std::vector<eh_index>> Equihash::OptimisedSolve(const eh_HashState& base_state)
|
||||
template<unsigned int N, unsigned int K>
|
||||
std::set<std::vector<eh_index>> Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state)
|
||||
{
|
||||
assert(CollisionBitLength() + 1 < 8*sizeof(eh_index));
|
||||
eh_index init_size { 1 << (CollisionBitLength() + 1) };
|
||||
eh_index init_size { 1 << (CollisionBitLength + 1) };
|
||||
|
||||
// First run the algorithm with truncated indices
|
||||
|
||||
eh_index soln_size { 1 << k };
|
||||
eh_index soln_size { 1 << K };
|
||||
std::vector<eh_trunc*> partialSolns;
|
||||
{
|
||||
|
||||
|
@ -399,11 +380,11 @@ std::set<std::vector<eh_index>> Equihash::OptimisedSolve(const eh_HashState& bas
|
|||
std::vector<TruncatedStepRow> Xt;
|
||||
Xt.reserve(init_size);
|
||||
for (eh_index i = 0; i < init_size; i++) {
|
||||
Xt.emplace_back(n, base_state, i, CollisionBitLength() + 1);
|
||||
Xt.emplace_back(N, base_state, i, CollisionBitLength + 1);
|
||||
}
|
||||
|
||||
// 3) Repeat step 2 until 2n/(k+1) bits remain
|
||||
for (int r = 1; r < k && Xt.size() > 0; r++) {
|
||||
for (int r = 1; r < K && Xt.size() > 0; r++) {
|
||||
LogPrint("pow", "Round %d:\n", r);
|
||||
// 2a) Sort the list
|
||||
LogPrint("pow", "- Sorting list\n");
|
||||
|
@ -417,7 +398,7 @@ std::set<std::vector<eh_index>> Equihash::OptimisedSolve(const eh_HashState& bas
|
|||
// 2b) Find next set of unordered pairs with collisions on the next n/(k+1) bits
|
||||
int j = 1;
|
||||
while (i+j < Xt.size() &&
|
||||
HasCollision(Xt[i], Xt[i+j], CollisionByteLength())) {
|
||||
HasCollision(Xt[i], Xt[i+j], CollisionByteLength)) {
|
||||
j++;
|
||||
}
|
||||
|
||||
|
@ -426,7 +407,7 @@ std::set<std::vector<eh_index>> Equihash::OptimisedSolve(const eh_HashState& bas
|
|||
for (int m = l + 1; m < j; m++) {
|
||||
// We truncated, so don't check for distinct indices here
|
||||
Xc.push_back(Xt[i+l] ^ Xt[i+m]);
|
||||
Xc.back().TrimHash(CollisionByteLength());
|
||||
Xc.back().TrimHash(CollisionByteLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,7 +458,7 @@ std::set<std::vector<eh_index>> Equihash::OptimisedSolve(const eh_HashState& bas
|
|||
// Now for each solution run the algorithm again to recreate the indices
|
||||
LogPrint("pow", "Culling solutions\n");
|
||||
std::set<std::vector<eh_index>> solns;
|
||||
eh_index recreate_size { UntruncateIndex(1, 0, CollisionBitLength() + 1) };
|
||||
eh_index recreate_size { UntruncateIndex(1, 0, CollisionBitLength + 1) };
|
||||
int invalidCount = 0;
|
||||
for (eh_trunc* partialSoln : partialSolns) {
|
||||
// 1) Generate first list of possibilities
|
||||
|
@ -487,8 +468,8 @@ std::set<std::vector<eh_index>> Equihash::OptimisedSolve(const eh_HashState& bas
|
|||
std::vector<FullStepRow> ic;
|
||||
ic.reserve(recreate_size);
|
||||
for (eh_index j = 0; j < recreate_size; j++) {
|
||||
eh_index newIndex { UntruncateIndex(partialSoln[i], j, CollisionBitLength() + 1) };
|
||||
ic.emplace_back(n, base_state, newIndex);
|
||||
eh_index newIndex { UntruncateIndex(partialSoln[i], j, CollisionBitLength + 1) };
|
||||
ic.emplace_back(N, base_state, newIndex);
|
||||
}
|
||||
X.push_back(ic);
|
||||
}
|
||||
|
@ -505,7 +486,7 @@ std::set<std::vector<eh_index>> Equihash::OptimisedSolve(const eh_HashState& bas
|
|||
ic.reserve(X[v].size() + X[v+1].size());
|
||||
ic.insert(ic.end(), X[v+1].begin(), X[v+1].end());
|
||||
std::sort(ic.begin(), ic.end());
|
||||
CollideBranches(ic, CollisionByteLength(), CollisionBitLength() + 1, partialSoln[(1<<r)*v], partialSoln[(1<<r)*(v+1)]);
|
||||
CollideBranches(ic, CollisionByteLength, CollisionBitLength + 1, partialSoln[(1<<r)*v], partialSoln[(1<<r)*(v+1)]);
|
||||
|
||||
// 2v) Check if this has become an invalid solution
|
||||
if (ic.size() == 0)
|
||||
|
@ -535,9 +516,10 @@ deletesolution:
|
|||
return solns;
|
||||
}
|
||||
|
||||
bool Equihash::IsValidSolution(const eh_HashState& base_state, std::vector<eh_index> soln)
|
||||
template<unsigned int N, unsigned int K>
|
||||
bool Equihash<N,K>::IsValidSolution(const eh_HashState& base_state, std::vector<eh_index> soln)
|
||||
{
|
||||
eh_index soln_size { 1u << k };
|
||||
eh_index soln_size { 1u << K };
|
||||
if (soln.size() != soln_size) {
|
||||
LogPrint("pow", "Invalid solution size: %d\n", soln.size());
|
||||
return false;
|
||||
|
@ -546,13 +528,13 @@ bool Equihash::IsValidSolution(const eh_HashState& base_state, std::vector<eh_in
|
|||
std::vector<FullStepRow> X;
|
||||
X.reserve(soln_size);
|
||||
for (eh_index i : soln) {
|
||||
X.emplace_back(n, base_state, i);
|
||||
X.emplace_back(N, base_state, i);
|
||||
}
|
||||
|
||||
while (X.size() > 1) {
|
||||
std::vector<FullStepRow> Xc;
|
||||
for (int i = 0; i < X.size(); i += 2) {
|
||||
if (!HasCollision(X[i], X[i+1], CollisionByteLength())) {
|
||||
if (!HasCollision(X[i], X[i+1], CollisionByteLength)) {
|
||||
LogPrint("pow", "Invalid solution: invalid collision length between StepRows\n");
|
||||
LogPrint("pow", "X[i] = %s\n", X[i].GetHex());
|
||||
LogPrint("pow", "X[i+1] = %s\n", X[i+1].GetHex());
|
||||
|
@ -567,7 +549,7 @@ bool Equihash::IsValidSolution(const eh_HashState& base_state, std::vector<eh_in
|
|||
return false;
|
||||
}
|
||||
Xc.push_back(X[i] ^ X[i+1]);
|
||||
Xc.back().TrimHash(CollisionByteLength());
|
||||
Xc.back().TrimHash(CollisionByteLength);
|
||||
}
|
||||
X = Xc;
|
||||
}
|
||||
|
@ -575,3 +557,15 @@ bool Equihash::IsValidSolution(const eh_HashState& base_state, std::vector<eh_in
|
|||
assert(X.size() == 1);
|
||||
return X[0].IsZero();
|
||||
}
|
||||
|
||||
// Explicit instantiations for Equihash<96,5>
|
||||
template int Equihash<96,5>::InitialiseState(eh_HashState& base_state);
|
||||
template std::set<std::vector<eh_index>> Equihash<96,5>::BasicSolve(const eh_HashState& base_state);
|
||||
template std::set<std::vector<eh_index>> Equihash<96,5>::OptimisedSolve(const eh_HashState& base_state);
|
||||
template bool Equihash<96,5>::IsValidSolution(const eh_HashState& base_state, std::vector<eh_index> soln);
|
||||
|
||||
// Explicit instantiations for Equihash<48,5>
|
||||
template int Equihash<48,5>::InitialiseState(eh_HashState& base_state);
|
||||
template std::set<std::vector<eh_index>> Equihash<48,5>::BasicSolve(const eh_HashState& base_state);
|
||||
template std::set<std::vector<eh_index>> Equihash<48,5>::OptimisedSolve(const eh_HashState& base_state);
|
||||
template bool Equihash<48,5>::IsValidSolution(const eh_HashState& base_state, std::vector<eh_index> soln);
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
typedef crypto_generichash_blake2b_state eh_HashState;
|
||||
typedef uint32_t eh_index;
|
||||
typedef uint8_t eh_trunc;
|
||||
|
||||
struct invalid_params { };
|
||||
|
||||
class StepRow
|
||||
{
|
||||
protected:
|
||||
|
@ -96,17 +96,20 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template<unsigned int N, unsigned int K>
|
||||
class Equihash
|
||||
{
|
||||
private:
|
||||
unsigned int n;
|
||||
unsigned int k;
|
||||
BOOST_STATIC_ASSERT(K < N);
|
||||
BOOST_STATIC_ASSERT(N % 8 == 0);
|
||||
BOOST_STATIC_ASSERT((N/(K+1)) % 8 == 0);
|
||||
BOOST_STATIC_ASSERT((N/(K+1)) + 1 < 8*sizeof(eh_index));
|
||||
|
||||
public:
|
||||
Equihash(unsigned int n, unsigned int k);
|
||||
enum { CollisionBitLength=N/(K+1) };
|
||||
enum { CollisionByteLength=CollisionBitLength/8 };
|
||||
|
||||
inline unsigned int CollisionBitLength() { return n/(k+1); }
|
||||
inline unsigned int CollisionByteLength() { return CollisionBitLength()/8; }
|
||||
Equihash() { }
|
||||
|
||||
int InitialiseState(eh_HashState& base_state);
|
||||
std::set<std::vector<eh_index>> BasicSolve(const eh_HashState& base_state);
|
||||
|
@ -114,4 +117,43 @@ public:
|
|||
bool IsValidSolution(const eh_HashState& base_state, std::vector<eh_index> soln);
|
||||
};
|
||||
|
||||
static Equihash<96,5> Eh965;
|
||||
static Equihash<48,5> Eh485;
|
||||
|
||||
#define EhInitialiseState(n, k, base_state) \
|
||||
if (n == 96 && k == 5) { \
|
||||
Eh965.InitialiseState(base_state); \
|
||||
} else if (n == 48 && k == 5) { \
|
||||
Eh485.InitialiseState(base_state); \
|
||||
} else { \
|
||||
throw std::invalid_argument("Unsupported Equihash parameters"); \
|
||||
}
|
||||
|
||||
#define EhBasicSolve(n, k, base_state, solns) \
|
||||
if (n == 96 && k == 5) { \
|
||||
solns = Eh965.BasicSolve(base_state); \
|
||||
} else if (n == 48 && k == 5) { \
|
||||
solns = Eh485.BasicSolve(base_state); \
|
||||
} else { \
|
||||
throw std::invalid_argument("Unsupported Equihash parameters"); \
|
||||
}
|
||||
|
||||
#define EhOptimisedSolve(n, k, base_state, solns) \
|
||||
if (n == 96 && k == 5) { \
|
||||
solns = Eh965.OptimisedSolve(base_state); \
|
||||
} else if (n == 48 && k == 5) { \
|
||||
solns = Eh485.OptimisedSolve(base_state); \
|
||||
} else { \
|
||||
throw std::invalid_argument("Unsupported Equihash parameters"); \
|
||||
}
|
||||
|
||||
#define EhIsValidSolution(n, k, base_state, soln, ret) \
|
||||
if (n == 96 && k == 5) { \
|
||||
ret = Eh965.IsValidSolution(base_state, soln); \
|
||||
} else if (n == 48 && k == 5) { \
|
||||
ret = Eh485.IsValidSolution(base_state, soln); \
|
||||
} else { \
|
||||
throw std::invalid_argument("Unsupported Equihash parameters"); \
|
||||
}
|
||||
|
||||
#endif // BITCOIN_EQUIHASH_H
|
||||
|
|
|
@ -443,7 +443,8 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
CReserveKey reservekey(pwallet);
|
||||
unsigned int nExtraNonce = 0;
|
||||
|
||||
Equihash eh {chainparams.EquihashN(), chainparams.EquihashK()};
|
||||
unsigned int n = chainparams.EquihashN();
|
||||
unsigned int k = chainparams.EquihashK();
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
|
@ -489,7 +490,7 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
while (true) {
|
||||
// Hash state
|
||||
crypto_generichash_blake2b_state state;
|
||||
eh.InitialiseState(state);
|
||||
EhInitialiseState(n, k, state);
|
||||
|
||||
// I = the block header minus nonce and solution.
|
||||
CEquihashInput I{*pblock};
|
||||
|
@ -512,7 +513,8 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
// (x_1, x_2, ...) = A(I, V, n, k)
|
||||
LogPrint("pow", "Running Equihash solver with nNonce = %s\n",
|
||||
pblock->nNonce.ToString());
|
||||
std::set<std::vector<unsigned int>> solns = eh.BasicSolve(curr_state);
|
||||
std::set<std::vector<unsigned int>> solns;
|
||||
EhBasicSolve(n, k, curr_state, solns);
|
||||
LogPrint("pow", "Solutions: %d\n", solns.size());
|
||||
|
||||
// Write the solution to the hash and compute the result.
|
||||
|
|
|
@ -88,11 +88,12 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
|
|||
|
||||
bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params)
|
||||
{
|
||||
Equihash eh {params.EquihashN(), params.EquihashK()};
|
||||
unsigned int n = params.EquihashN();
|
||||
unsigned int k = params.EquihashK();
|
||||
|
||||
// Hash state
|
||||
crypto_generichash_blake2b_state state;
|
||||
eh.InitialiseState(state);
|
||||
EhInitialiseState(n, k, state);
|
||||
|
||||
// I = the block header minus nonce and solution.
|
||||
CEquihashInput I{*pblock};
|
||||
|
@ -104,7 +105,9 @@ bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& param
|
|||
// H(I||V||...
|
||||
crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size());
|
||||
|
||||
if (!eh.IsValidSolution(state, pblock->nSolution))
|
||||
bool isValid;
|
||||
EhIsValidSolution(n, k, state, pblock->nSolution, isValid);
|
||||
if (!isValid)
|
||||
return error("CheckEquihashSolution(): invalid solution");
|
||||
|
||||
return true;
|
||||
|
|
|
@ -150,7 +150,8 @@ Value generate(const Array& params, bool fHelp)
|
|||
}
|
||||
unsigned int nExtraNonce = 0;
|
||||
Array blockHashes;
|
||||
Equihash eh {Params().EquihashN(), Params().EquihashK()};
|
||||
unsigned int n = Params().EquihashN();
|
||||
unsigned int k = Params().EquihashK();
|
||||
while (nHeight < nHeightEnd)
|
||||
{
|
||||
auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
|
||||
|
@ -164,7 +165,7 @@ Value generate(const Array& params, bool fHelp)
|
|||
|
||||
// Hash state
|
||||
crypto_generichash_blake2b_state eh_state;
|
||||
eh.InitialiseState(eh_state);
|
||||
EhInitialiseState(n, k, eh_state);
|
||||
|
||||
// I = the block header minus nonce and solution.
|
||||
CEquihashInput I{*pblock};
|
||||
|
@ -187,10 +188,13 @@ Value generate(const Array& params, bool fHelp)
|
|||
pblock->nNonce.size());
|
||||
|
||||
// (x_1, x_2, ...) = A(I, V, n, k)
|
||||
std::set<std::vector<unsigned int>> solns = eh.BasicSolve(curr_state);
|
||||
std::set<std::vector<unsigned int>> solns;
|
||||
EhBasicSolve(n, k, curr_state, solns);
|
||||
|
||||
for (auto soln : solns) {
|
||||
assert(eh.IsValidSolution(curr_state, soln));
|
||||
bool isValid;
|
||||
EhIsValidSolution(n, k, curr_state, soln, isValid);
|
||||
assert(isValid);
|
||||
pblock->nSolution = soln;
|
||||
|
||||
if (CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
|
||||
|
|
|
@ -41,16 +41,16 @@ void PrintSolutions(std::stringstream &strm, std::set<std::vector<uint32_t>> sol
|
|||
}
|
||||
|
||||
void TestEquihashSolvers(unsigned int n, unsigned int k, const std::string &I, const arith_uint256 &nonce, const std::set<std::vector<uint32_t>> &solns) {
|
||||
Equihash eh {n, k};
|
||||
crypto_generichash_blake2b_state state;
|
||||
eh.InitialiseState(state);
|
||||
EhInitialiseState(n, k, state);
|
||||
uint256 V = ArithToUint256(nonce);
|
||||
BOOST_TEST_MESSAGE("Running solver: n = " << n << ", k = " << k << ", I = " << I << ", V = " << V.GetHex());
|
||||
crypto_generichash_blake2b_update(&state, (unsigned char*)&I[0], I.size());
|
||||
crypto_generichash_blake2b_update(&state, V.begin(), V.size());
|
||||
|
||||
// First test the basic solver
|
||||
std::set<std::vector<uint32_t>> ret = eh.BasicSolve(state);
|
||||
std::set<std::vector<uint32_t>> ret;
|
||||
EhBasicSolve(n, k, state, ret);
|
||||
BOOST_TEST_MESSAGE("[Basic] Number of solutions: " << ret.size());
|
||||
std::stringstream strm;
|
||||
PrintSolutions(strm, ret);
|
||||
|
@ -58,7 +58,8 @@ void TestEquihashSolvers(unsigned int n, unsigned int k, const std::string &I, c
|
|||
BOOST_CHECK(ret == solns);
|
||||
|
||||
// The optimised solver should have the exact same result
|
||||
std::set<std::vector<uint32_t>> retOpt = eh.OptimisedSolve(state);
|
||||
std::set<std::vector<uint32_t>> retOpt;
|
||||
EhOptimisedSolve(n, k, state, retOpt);
|
||||
BOOST_TEST_MESSAGE("[Optimised] Number of solutions: " << retOpt.size());
|
||||
strm.str("");
|
||||
PrintSolutions(strm, retOpt);
|
||||
|
@ -68,9 +69,8 @@ void TestEquihashSolvers(unsigned int n, unsigned int k, const std::string &I, c
|
|||
}
|
||||
|
||||
void TestEquihashValidator(unsigned int n, unsigned int k, const std::string &I, const arith_uint256 &nonce, std::vector<uint32_t> soln, bool expected) {
|
||||
Equihash eh {n, k};
|
||||
crypto_generichash_blake2b_state state;
|
||||
eh.InitialiseState(state);
|
||||
EhInitialiseState(n, k, state);
|
||||
uint256 V = ArithToUint256(nonce);
|
||||
crypto_generichash_blake2b_update(&state, (unsigned char*)&I[0], I.size());
|
||||
crypto_generichash_blake2b_update(&state, V.begin(), V.size());
|
||||
|
@ -78,7 +78,9 @@ void TestEquihashValidator(unsigned int n, unsigned int k, const std::string &I,
|
|||
std::stringstream strm;
|
||||
PrintSolution(strm, soln);
|
||||
BOOST_TEST_MESSAGE(strm.str());
|
||||
BOOST_CHECK(eh.IsValidSolution(state, soln) == expected);
|
||||
bool isValid;
|
||||
EhIsValidSolution(n, k, state, soln, isValid);
|
||||
BOOST_CHECK(isValid == expected);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(solver_testvectors) {
|
||||
|
|
|
@ -100,9 +100,10 @@ double benchmark_solve_equihash()
|
|||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << I;
|
||||
|
||||
Equihash eh {Params(CBaseChainParams::MAIN).EquihashN(), Params(CBaseChainParams::MAIN).EquihashK()};
|
||||
unsigned int n = Params(CBaseChainParams::MAIN).EquihashN();
|
||||
unsigned int k = Params(CBaseChainParams::MAIN).EquihashK();
|
||||
crypto_generichash_blake2b_state eh_state;
|
||||
eh.InitialiseState(eh_state);
|
||||
EhInitialiseState(n, k, eh_state);
|
||||
crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size());
|
||||
|
||||
uint256 nonce;
|
||||
|
@ -112,7 +113,8 @@ double benchmark_solve_equihash()
|
|||
nonce.size());
|
||||
|
||||
timer_start();
|
||||
eh.BasicSolve(eh_state);
|
||||
std::set<std::vector<unsigned int>> solns;
|
||||
EhBasicSolve(n, k, eh_state, solns);
|
||||
return timer_stop();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue