Auto merge of #4608 - str4d:post-heartwood-cleanups, r=nuttycom
Post-Heartwood cleanups The C++ Equihash validator is removed; the Rust validator is now used unconditionally for the entire chain. Changes made to enable contextually switching between the two validators have been reverted. Also fixes a segfault that could occur on reindex during consensus-related development.
This commit is contained in:
commit
b4ec903ac4
|
@ -16,6 +16,8 @@
|
|||
#include "config/bitcoin-config.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
|
||||
#include "compat/endian.h"
|
||||
#include "crypto/equihash.h"
|
||||
#include "util.h"
|
||||
|
@ -324,7 +326,6 @@ std::shared_ptr<eh_trunc> TruncatedStepRow<WIDTH>::GetTruncatedIndices(size_t le
|
|||
return p;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
template<unsigned int N, unsigned int K>
|
||||
bool Equihash<N,K>::BasicSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
|
@ -717,100 +718,41 @@ invalidsolution:
|
|||
|
||||
return false;
|
||||
}
|
||||
#endif // ENABLE_MINING
|
||||
|
||||
template<unsigned int N, unsigned int K>
|
||||
bool Equihash<N,K>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln)
|
||||
{
|
||||
if (soln.size() != SolutionWidth) {
|
||||
LogPrint("pow", "Invalid solution length: %d (expected %d)\n",
|
||||
soln.size(), SolutionWidth);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<FullStepRow<FinalFullWidth>> X;
|
||||
X.reserve(1 << K);
|
||||
unsigned char tmpHash[HashOutput];
|
||||
for (eh_index i : GetIndicesFromMinimal(soln, CollisionBitLength)) {
|
||||
GenerateHash(base_state, i/IndicesPerHashOutput, tmpHash, HashOutput);
|
||||
X.emplace_back(tmpHash+((i % IndicesPerHashOutput) * N/8),
|
||||
N/8, HashLength, CollisionBitLength, i);
|
||||
}
|
||||
|
||||
size_t hashLen = HashLength;
|
||||
size_t lenIndices = sizeof(eh_index);
|
||||
while (X.size() > 1) {
|
||||
std::vector<FullStepRow<FinalFullWidth>> Xc;
|
||||
for (int i = 0; i < X.size(); i += 2) {
|
||||
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(hashLen));
|
||||
LogPrint("pow", "X[i+1] = %s\n", X[i+1].GetHex(hashLen));
|
||||
return false;
|
||||
}
|
||||
if (X[i+1].IndicesBefore(X[i], hashLen, lenIndices)) {
|
||||
LogPrint("pow", "Invalid solution: Index tree incorrectly ordered\n");
|
||||
return false;
|
||||
}
|
||||
if (!DistinctIndices(X[i], X[i+1], hashLen, lenIndices)) {
|
||||
LogPrint("pow", "Invalid solution: duplicate indices\n");
|
||||
return false;
|
||||
}
|
||||
Xc.emplace_back(X[i], X[i+1], hashLen, lenIndices, CollisionByteLength);
|
||||
}
|
||||
X = Xc;
|
||||
hashLen -= CollisionByteLength;
|
||||
lenIndices *= 2;
|
||||
}
|
||||
|
||||
assert(X.size() == 1);
|
||||
return X[0].IsZero(hashLen);
|
||||
}
|
||||
|
||||
// Explicit instantiations for Equihash<96,3>
|
||||
template int Equihash<96,3>::InitialiseState(eh_HashState& base_state);
|
||||
#ifdef ENABLE_MINING
|
||||
template bool Equihash<96,3>::BasicSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
template bool Equihash<96,3>::OptimisedSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
#endif
|
||||
template bool Equihash<96,3>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
|
||||
|
||||
// Explicit instantiations for Equihash<200,9>
|
||||
template int Equihash<200,9>::InitialiseState(eh_HashState& base_state);
|
||||
#ifdef ENABLE_MINING
|
||||
template bool Equihash<200,9>::BasicSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
template bool Equihash<200,9>::OptimisedSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
#endif
|
||||
template bool Equihash<200,9>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
|
||||
|
||||
// Explicit instantiations for Equihash<96,5>
|
||||
template int Equihash<96,5>::InitialiseState(eh_HashState& base_state);
|
||||
#ifdef ENABLE_MINING
|
||||
template bool Equihash<96,5>::BasicSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
template bool Equihash<96,5>::OptimisedSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
#endif
|
||||
template bool Equihash<96,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
|
||||
|
||||
// Explicit instantiations for Equihash<48,5>
|
||||
template int Equihash<48,5>::InitialiseState(eh_HashState& base_state);
|
||||
#ifdef ENABLE_MINING
|
||||
template bool Equihash<48,5>::BasicSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
template bool Equihash<48,5>::OptimisedSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
#endif
|
||||
template bool Equihash<48,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
|
||||
|
||||
#endif // ENABLE_MINING
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#ifndef BITCOIN_EQUIHASH_H
|
||||
#define BITCOIN_EQUIHASH_H
|
||||
#ifdef ENABLE_MINING
|
||||
|
||||
#include "crypto/sha256.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
@ -183,15 +184,12 @@ public:
|
|||
Equihash() { }
|
||||
|
||||
int InitialiseState(eh_HashState& base_state);
|
||||
#ifdef ENABLE_MINING
|
||||
bool BasicSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
bool OptimisedSolve(const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled);
|
||||
#endif
|
||||
bool IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
|
||||
};
|
||||
|
||||
#include "equihash.tcc"
|
||||
|
@ -214,7 +212,6 @@ static Equihash<48,5> Eh48_5;
|
|||
throw std::invalid_argument("Unsupported Equihash parameters"); \
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
inline bool EhBasicSolve(unsigned int n, unsigned int k, const eh_HashState& base_state,
|
||||
const std::function<bool(std::vector<unsigned char>)> validBlock,
|
||||
const std::function<bool(EhSolverCancelCheck)> cancelled)
|
||||
|
@ -264,18 +261,4 @@ inline bool EhOptimisedSolveUncancellable(unsigned int n, unsigned int k, const
|
|||
}
|
||||
#endif // ENABLE_MINING
|
||||
|
||||
#define EhIsValidSolution(n, k, base_state, soln, ret) \
|
||||
if (n == 96 && k == 3) { \
|
||||
ret = Eh96_3.IsValidSolution(base_state, soln); \
|
||||
} else if (n == 200 && k == 9) { \
|
||||
ret = Eh200_9.IsValidSolution(base_state, soln); \
|
||||
} else if (n == 96 && k == 5) { \
|
||||
ret = Eh96_5.IsValidSolution(base_state, soln); \
|
||||
} else if (n == 48 && k == 5) { \
|
||||
ret = Eh48_5.IsValidSolution(base_state, soln); \
|
||||
} else { \
|
||||
ret = false; \
|
||||
throw std::invalid_argument("Unsupported Equihash parameters"); \
|
||||
}
|
||||
|
||||
#endif // BITCOIN_EQUIHASH_H
|
||||
|
|
28
src/main.cpp
28
src/main.cpp
|
@ -1824,7 +1824,7 @@ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHea
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, int nHeight, const Consensus::Params& consensusParams)
|
||||
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams)
|
||||
{
|
||||
block.SetNull();
|
||||
|
||||
|
@ -1842,7 +1842,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, int nHeight, con
|
|||
}
|
||||
|
||||
// Check the header
|
||||
if (!(CheckEquihashSolution(&block, nHeight, consensusParams) &&
|
||||
if (!(CheckEquihashSolution(&block, consensusParams) &&
|
||||
CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)))
|
||||
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
|
||||
|
||||
|
@ -1851,7 +1851,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, int nHeight, con
|
|||
|
||||
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
|
||||
{
|
||||
if (!ReadBlockFromDisk(block, pindex->GetBlockPos(), pindex->nHeight, consensusParams))
|
||||
if (!ReadBlockFromDisk(block, pindex->GetBlockPos(), consensusParams))
|
||||
return false;
|
||||
if (block.GetHash() != pindex->GetBlockHash())
|
||||
return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
|
||||
|
@ -3979,19 +3979,13 @@ bool CheckBlockHeader(
|
|||
const CChainParams& chainparams,
|
||||
bool fCheckPOW)
|
||||
{
|
||||
auto consensusParams = chainparams.GetConsensus();
|
||||
|
||||
// Check block version
|
||||
if (block.nVersion < MIN_BLOCK_VERSION)
|
||||
return state.DoS(100, error("CheckBlockHeader(): block version too low"),
|
||||
REJECT_INVALID, "version-too-low");
|
||||
|
||||
// Check Equihash solution is valid. The main check is in ContextualCheckBlockHeader,
|
||||
// because we currently need to know the block height. That function skips the genesis
|
||||
// block because it has no previous block, so we check it specifically here.
|
||||
if (fCheckPOW &&
|
||||
block.GetHash() == consensusParams.hashGenesisBlock &&
|
||||
!CheckEquihashSolution(&block, 0, consensusParams))
|
||||
// Check Equihash solution is valid
|
||||
if (fCheckPOW && !CheckEquihashSolution(&block, chainparams.GetConsensus()))
|
||||
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),
|
||||
REJECT_INVALID, "invalid-solution");
|
||||
|
||||
|
@ -4068,8 +4062,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state,
|
|||
|
||||
bool ContextualCheckBlockHeader(
|
||||
const CBlockHeader& block, CValidationState& state,
|
||||
const CChainParams& chainParams, CBlockIndex * const pindexPrev,
|
||||
bool fCheckPOW)
|
||||
const CChainParams& chainParams, CBlockIndex * const pindexPrev)
|
||||
{
|
||||
const Consensus::Params& consensusParams = chainParams.GetConsensus();
|
||||
uint256 hash = block.GetHash();
|
||||
|
@ -4081,11 +4074,6 @@ bool ContextualCheckBlockHeader(
|
|||
|
||||
int nHeight = pindexPrev->nHeight+1;
|
||||
|
||||
// Check Equihash solution is valid
|
||||
if (fCheckPOW && !CheckEquihashSolution(&block, nHeight, consensusParams))
|
||||
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),
|
||||
REJECT_INVALID, "invalid-solution");
|
||||
|
||||
// Check proof of work
|
||||
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) {
|
||||
return state.DoS(100, error("%s: incorrect proof of work", __func__),
|
||||
|
@ -4377,7 +4365,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
|
|||
auto verifier = libzcash::ProofVerifier::Disabled();
|
||||
|
||||
// NOTE: CheckBlockHeader is called by CheckBlock
|
||||
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, fCheckPOW))
|
||||
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev))
|
||||
return false;
|
||||
if (!CheckBlock(block, state, chainparams, verifier, fCheckPOW, fCheckMerkleRoot))
|
||||
return false;
|
||||
|
@ -5173,7 +5161,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
|
|||
std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
|
||||
while (range.first != range.second) {
|
||||
std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
|
||||
if (ReadBlockFromDisk(block, it->second, mapBlockIndex[head]->nHeight, chainparams.GetConsensus()))
|
||||
if (ReadBlockFromDisk(block, it->second, chainparams.GetConsensus()))
|
||||
{
|
||||
LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
|
||||
head.ToString());
|
||||
|
|
|
@ -436,7 +436,7 @@ bool GetTimestampIndex(unsigned int high, unsigned int low, bool fActiveOnly,
|
|||
|
||||
/** Functions for disk access for blocks */
|
||||
bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
|
||||
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, int nHeight, const Consensus::Params& consensusParams);
|
||||
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams);
|
||||
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
|
||||
|
||||
/** Functions for validating blocks and updating the block tree */
|
||||
|
@ -454,8 +454,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state,
|
|||
* By "context", we mean only the previous block headers, but not the UTXO
|
||||
* set; UTXO-related validity checks are done in ConnectBlock(). */
|
||||
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state,
|
||||
const CChainParams& chainparams, CBlockIndex *pindexPrev,
|
||||
bool fCheckPOW = true);
|
||||
const CChainParams& chainparams, CBlockIndex *pindexPrev);
|
||||
bool ContextualCheckBlock(const CBlock& block, CValidationState& state,
|
||||
const CChainParams& chainparams, CBlockIndex *pindexPrev);
|
||||
|
||||
|
|
33
src/pow.cpp
33
src/pow.cpp
|
@ -14,7 +14,6 @@
|
|||
#include "uint256.h"
|
||||
|
||||
#include <librustzcash.h>
|
||||
#include "sodium.h"
|
||||
|
||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||
{
|
||||
|
@ -93,42 +92,22 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
|
|||
return bnNew.GetCompact();
|
||||
}
|
||||
|
||||
bool CheckEquihashSolution(const CBlockHeader *pblock, int nHeight, const Consensus::Params& params)
|
||||
bool CheckEquihashSolution(const CBlockHeader *pblock, const Consensus::Params& params)
|
||||
{
|
||||
unsigned int n = params.nEquihashN;
|
||||
unsigned int k = params.nEquihashK;
|
||||
|
||||
// Hash state
|
||||
crypto_generichash_blake2b_state state;
|
||||
EhInitialiseState(n, k, state);
|
||||
|
||||
// I = the block header minus nonce and solution.
|
||||
CEquihashInput I{*pblock};
|
||||
// I||V
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << I;
|
||||
|
||||
// From Heartwood activation, check with the Rust validator
|
||||
if (params.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_HEARTWOOD)) {
|
||||
return librustzcash_eh_isvalid(
|
||||
n, k,
|
||||
(unsigned char*)&ss[0], ss.size(),
|
||||
pblock->nNonce.begin(), pblock->nNonce.size(),
|
||||
pblock->nSolution.data(), pblock->nSolution.size());
|
||||
}
|
||||
|
||||
// Before Heartwood activation, check with the C++ validator
|
||||
ss << pblock->nNonce;
|
||||
|
||||
// H(I||V||...
|
||||
crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size());
|
||||
|
||||
bool isValid;
|
||||
EhIsValidSolution(n, k, state, pblock->nSolution, isValid);
|
||||
if (!isValid)
|
||||
return error("CheckEquihashSolution(): invalid solution");
|
||||
|
||||
return true;
|
||||
return librustzcash_eh_isvalid(
|
||||
n, k,
|
||||
(unsigned char*)&ss[0], ss.size(),
|
||||
pblock->nNonce.begin(), pblock->nNonce.size(),
|
||||
pblock->nSolution.data(), pblock->nSolution.size());
|
||||
}
|
||||
|
||||
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
|
||||
|
|
|
@ -23,7 +23,7 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
|
|||
int nextHeight);
|
||||
|
||||
/** Check whether the Equihash solution in a block header is valid */
|
||||
bool CheckEquihashSolution(const CBlockHeader *pblock, int nHeight, const Consensus::Params&);
|
||||
bool CheckEquihashSolution(const CBlockHeader *pblock, const Consensus::Params&);
|
||||
|
||||
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
|
||||
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
|
||||
|
|
|
@ -91,22 +91,13 @@ void TestEquihashValidator(unsigned int n, unsigned int k, const std::string &I,
|
|||
size_t cBitLen { n/(k+1) };
|
||||
auto minimal = GetMinimalFromIndices(soln, cBitLen);
|
||||
|
||||
// First test the C++ validator
|
||||
crypto_generichash_blake2b_state 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());
|
||||
BOOST_TEST_MESSAGE("Running validator: n = " << n << ", k = " << k << ", I = " << I << ", V = " << V.GetHex() << ", expected = " << expected << ", soln =");
|
||||
std::stringstream strm;
|
||||
PrintSolution(strm, soln);
|
||||
BOOST_TEST_MESSAGE(strm.str());
|
||||
bool isValid;
|
||||
EhIsValidSolution(n, k, state, minimal, isValid);
|
||||
BOOST_CHECK(isValid == expected);
|
||||
|
||||
// The Rust validator should have the exact same result
|
||||
isValid = librustzcash_eh_isvalid(
|
||||
bool isValid = librustzcash_eh_isvalid(
|
||||
n, k,
|
||||
(unsigned char*)&I[0], I.size(),
|
||||
V.begin(), V.size(),
|
||||
|
@ -216,12 +207,8 @@ BOOST_AUTO_TEST_CASE(validator_allbitsmatter) {
|
|||
// Initialize the state according to one of the test vectors above.
|
||||
unsigned int n = 96;
|
||||
unsigned int k = 5;
|
||||
crypto_generichash_blake2b_state state;
|
||||
EhInitialiseState(n, k, state);
|
||||
uint256 V = ArithToUint256(1);
|
||||
std::string I = "Equihash is an asymmetric PoW based on the Generalised Birthday problem.";
|
||||
crypto_generichash_blake2b_update(&state, (unsigned char*)&I[0], I.size());
|
||||
crypto_generichash_blake2b_update(&state, V.begin(), V.size());
|
||||
|
||||
// Encode the correct solution.
|
||||
std::vector<uint32_t> soln = {2261, 15185, 36112, 104243, 23779, 118390, 118332, 130041, 32642, 69878, 76925, 80080, 45858, 116805, 92842, 111026, 15972, 115059, 85191, 90330, 68190, 122819, 81830, 91132, 23460, 49807, 52426, 80391, 69567, 114474, 104973, 122568};
|
||||
|
@ -229,9 +216,6 @@ BOOST_AUTO_TEST_CASE(validator_allbitsmatter) {
|
|||
std::vector<unsigned char> sol_char = GetMinimalFromIndices(soln, cBitLen);
|
||||
|
||||
// Prove that the solution is valid.
|
||||
bool isValid;
|
||||
EhIsValidSolution(n, k, state, sol_char, isValid);
|
||||
BOOST_CHECK(isValid == true);
|
||||
BOOST_CHECK(librustzcash_eh_isvalid(
|
||||
n, k,
|
||||
(unsigned char*)&I[0], I.size(),
|
||||
|
@ -242,8 +226,6 @@ BOOST_AUTO_TEST_CASE(validator_allbitsmatter) {
|
|||
for (size_t i = 0; i < sol_char.size() * 8; i++) {
|
||||
std::vector<unsigned char> mutated = sol_char;
|
||||
mutated.at(i/8) ^= (1 << (i % 8));
|
||||
EhIsValidSolution(n, k, state, mutated, isValid);
|
||||
BOOST_CHECK(isValid == false);
|
||||
BOOST_CHECK(!librustzcash_eh_isvalid(
|
||||
n, k,
|
||||
(unsigned char*)&I[0], I.size(),
|
||||
|
|
|
@ -247,10 +247,12 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||
solns.insert(sol_char);
|
||||
}
|
||||
|
||||
bool ret;
|
||||
for (auto soln : solns) {
|
||||
EhIsValidSolution(n, k, curr_state, soln, ret);
|
||||
if (!ret) continue;
|
||||
if (!librustzcash_eh_isvalid(
|
||||
n, k,
|
||||
(unsigned char*)&ss[0], ss.size(),
|
||||
pblock->nNonce.begin(), pblock->nNonce.size(),
|
||||
soln.data(), soln.size())) continue;
|
||||
pblock->nSolution = soln;
|
||||
|
||||
CValidationState state;
|
||||
|
|
|
@ -204,7 +204,7 @@ double benchmark_verify_equihash()
|
|||
CBlockHeader genesis_header = genesis.GetBlockHeader();
|
||||
struct timeval tv_start;
|
||||
timer_start(tv_start);
|
||||
assert(CheckEquihashSolution(&genesis_header, 1, params.GetConsensus()));
|
||||
CheckEquihashSolution(&genesis_header, params.GetConsensus());
|
||||
return timer_stop(tv_start);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue