Browse Source

Add mostly-static checks on consistency of Equihash parameters, MAX_HEADERS_RESULTS, and MAX_PROTOCOL_MESSAGE_LENGTH.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
v1.0.9-lin
Daira Hopwood 8 years ago
parent
commit
c6a7e897bc
  1. 15
      src/chainparams.cpp
  2. 14
      src/crypto/equihash.cpp
  3. 4
      src/crypto/equihash.h
  4. 13
      src/gtest/test_block.cpp
  5. 4
      src/main.h
  6. 1
      src/primitives/block.h

15
src/chainparams.cpp

@ -3,7 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparams.h"
#include "main.h"
#include "crypto/equihash.h"
#include "util.h"
#include "utilstrencodings.h"
@ -59,8 +60,10 @@ public:
nMinerThreads = 0;
nMaxTipAge = 24 * 60 * 60;
nPruneAfterHeight = 100000;
nEquihashN = 200;
nEquihashK = 9;
const size_t N = 200, K = 9;
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K));
nEquihashN = N;
nEquihashK = K;
/**
* Build the genesis block. Note that the output of its generation
@ -222,8 +225,10 @@ public:
pchMessageStart[3] = 0x5f;
nMinerThreads = 1;
nMaxTipAge = 24 * 60 * 60;
nEquihashN = 48;
nEquihashK = 5;
const size_t N = 48, K = 5;
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K));
nEquihashN = N;
nEquihashK = K;
genesis.nTime = 1296688602;
genesis.nBits = 0x207fffff;
genesis.nNonce = uint256S("0x0000000000000000000000000000000000000000000000000000000000000002");

14
src/crypto/equihash.cpp

@ -419,10 +419,12 @@ bool Equihash<N,K>::BasicSolve(const eh_HashState& base_state,
for (int l = 0; l < j - 1; l++) {
for (int m = l + 1; m < j; m++) {
FullStepRow<FinalFullWidth> res(X[i+l], X[i+m], hashLen, lenIndices, 0);
if (DistinctIndices(X[i+l], X[i+m], hashLen, lenIndices) &&
validBlock(res.GetIndices(hashLen, 2*lenIndices,
CollisionBitLength))) {
return true;
if (DistinctIndices(X[i+l], X[i+m], hashLen, lenIndices)) {
auto soln = res.GetIndices(hashLen, 2*lenIndices, CollisionBitLength);
assert(soln.size() == equihash_solution_size(N, K));
if (validBlock(soln)) {
return true;
}
}
}
}
@ -691,7 +693,9 @@ bool Equihash<N,K>::OptimisedSolve(const eh_HashState& base_state,
// We are at the top of the tree
assert(X.size() == K+1);
for (FullStepRow<FinalFullWidth> row : *X[K]) {
solns.insert(row.GetIndices(hashLen, lenIndices, CollisionBitLength));
auto soln = row.GetIndices(hashLen, lenIndices, CollisionBitLength);
assert(soln.size() == equihash_solution_size(N, K));
solns.insert(soln);
}
for (auto soln : solns) {
if (validBlock(soln))

4
src/crypto/equihash.h

@ -155,6 +155,10 @@ class EhSolverCancelledException : public std::exception
inline constexpr const size_t max(const size_t A, const size_t B) { return A > B ? A : B; }
inline constexpr size_t equihash_solution_size(unsigned int N, unsigned int K) {
return (1 << K)*(N/(K+1)+1)/8;
}
template<unsigned int N, unsigned int K>
class Equihash
{

13
src/gtest/test_block.cpp

@ -0,0 +1,13 @@
#include <gtest/gtest.h>
#include "primitives/block.h"
TEST(block_tests, header_size_is_expected) {
// Dummy header with an empty Equihash solution.
CBlockHeader header;
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << header;
ASSERT_EQ(ss.size(), CBlockHeader::HEADER_SIZE);
}

4
src/main.h

@ -94,6 +94,10 @@ static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60;
/** Maximum length of reject messages. */
static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
#define equihash_parameters_acceptable(N, K) \
((CBlockHeader::HEADER_SIZE + equihash_solution_size(N, K))*MAX_HEADERS_RESULTS < \
MAX_PROTOCOL_MESSAGE_LENGTH-1000)
struct BlockHasher
{
size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); }

1
src/primitives/block.h

@ -21,6 +21,7 @@ class CBlockHeader
{
public:
// header
static const size_t HEADER_SIZE=4+32+32+32+4+4+32; // excluding Equihash solution
static const int32_t CURRENT_VERSION=4;
int32_t nVersion;
uint256 hashPrevBlock;

Loading…
Cancel
Save