Skip to content

Commit

Permalink
Enable an equihash parameter hard fork at a fixed block height
Browse files Browse the repository at this point in the history
  • Loading branch information
jc committed May 7, 2018
1 parent 4045199 commit df4df2c
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 18 deletions.
15 changes: 14 additions & 1 deletion src/chainparams.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -106,7 +107,7 @@ class CMainParams : public CChainParams {
// TODO: setup a DNSSeed
vSeeds.push_back(CDNSSeedData("btcprivate.org", "dnsseed.btcprivate.org"));
vSeeds.push_back(CDNSSeedData("btcprivate.co", "dnsseed.btcprivate.co"));

// guarantees the first 2 characters, when base58 encoded, are "b1"
base58Prefixes[PUBKEY_ADDRESS] = {0x13,0x25};
// guarantees the first 2 characters, when base58 encoded, are "bx"
Expand Down Expand Up @@ -152,6 +153,10 @@ class CMainParams : public CChainParams {

nForkStartHeight = 272991;
nForkHeightRange = 5467;

nEquihashForkHeight = 600001;
nEquihashNnew = 144;
nEquihashKnew = 5;
}
};
static CMainParams mainParams;
Expand Down Expand Up @@ -236,6 +241,10 @@ class CTestNetParams : public CMainParams {

nForkStartHeight = 10;
nForkHeightRange = 300;

nEquihashForkHeight = 500;
nEquihashNnew = 144;
nEquihashKnew = 5;
}
};
static CTestNetParams testNetParams;
Expand Down Expand Up @@ -305,6 +314,10 @@ class CRegTestParams : public CTestNetParams {

nForkStartHeight = 0;
nForkHeightRange = 0;

nEquihashForkHeight = 100;
nEquihashNnew = 96;
nEquihashKnew = 5;
}
};
static CRegTestParams regTestParams;
Expand Down
33 changes: 31 additions & 2 deletions src/chainparams.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand All @@ -9,6 +10,7 @@
#include "chainparamsbase.h"
#include "checkpoints.h"
#include "consensus/params.h"
#include "crypto/equihash.h"
#include "primitives/block.h"
#include "protocol.h"

Expand Down Expand Up @@ -62,8 +64,28 @@ class CChainParams
bool RequireStandard() const { return fRequireStandard; }
int64_t MaxTipAge() const { return nMaxTipAge; }
int64_t PruneAfterHeight() const { return nPruneAfterHeight; }
unsigned int EquihashN() const { return nEquihashN; }
unsigned int EquihashK() const { return nEquihashK; }

unsigned int EquihashN(int height) const
{
if(height >= nEquihashForkHeight)
return nEquihashNnew;

return nEquihashN;
}

unsigned int EquihashK(int height) const
{
if(height >= nEquihashForkHeight)
return nEquihashKnew;

return nEquihashK;
}

unsigned int EquihashSolutionWidth(int height) const
{
return EhSolutionWidth(EquihashN(height), EquihashK(height));
}

std::string CurrencyUnits() const { return strCurrencyUnits; }
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
Expand All @@ -80,6 +102,9 @@ class CChainParams

uint64_t ForkStartHeight() const { return nForkStartHeight; };
uint64_t ForkHeightRange() const { return nForkHeightRange; };

uint64_t EquihashForkHeight() const { return nEquihashForkHeight; };

protected:
CChainParams() {}

Expand Down Expand Up @@ -108,6 +133,10 @@ class CChainParams

uint64_t nForkStartHeight;
uint64_t nForkHeightRange;

uint64_t nEquihashForkHeight;
unsigned int nEquihashNnew;
unsigned int nEquihashKnew;
};

/**
Expand Down
14 changes: 14 additions & 0 deletions src/crypto/equihash.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2016 Jack Grigg
// Copyright (c) 2016 The Zcash developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -274,6 +275,7 @@ std::vector<unsigned char> FullStepRow<WIDTH>::GetIndices(size_t len, size_t len
}

template<size_t WIDTH>

bool HasCollision(StepRow<WIDTH>& a, StepRow<WIDTH>& b, int l)
{
// This doesn't need to be constant time.
Expand Down Expand Up @@ -792,6 +794,18 @@ template bool Equihash<200,9>::OptimisedSolve(const eh_HashState& base_state,
#endif
template bool Equihash<200,9>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);

// Explicit instantiations for Equihash<144,5>
template int Equihash<144,5>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING
template bool Equihash<144,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<144,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<144,5>::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
Expand Down
30 changes: 30 additions & 0 deletions src/crypto/equihash.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2016 Jack Grigg
// Copyright (c) 2016 The Zcash developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -199,12 +200,15 @@ static Equihash<96,3> Eh96_3;
static Equihash<200,9> Eh200_9;
static Equihash<96,5> Eh96_5;
static Equihash<48,5> Eh48_5;
static Equihash<144,5> Eh144_5;

#define EhInitialiseState(n, k, base_state) \
if (n == 96 && k == 3) { \
Eh96_3.InitialiseState(base_state); \
} else if (n == 200 && k == 9) { \
Eh200_9.InitialiseState(base_state); \
} else if (n == 144 && k == 5) { \
Eh144_5.InitialiseState(base_state); \
} else if (n == 96 && k == 5) { \
Eh96_5.InitialiseState(base_state); \
} else if (n == 48 && k == 5) { \
Expand All @@ -222,6 +226,8 @@ inline bool EhBasicSolve(unsigned int n, unsigned int k, const eh_HashState& bas
return Eh96_3.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 200 && k == 9) {
return Eh200_9.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 144 && k == 5) {
return Eh144_5.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 96 && k == 5) {
return Eh96_5.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 48 && k == 5) {
Expand All @@ -246,6 +252,8 @@ inline bool EhOptimisedSolve(unsigned int n, unsigned int k, const eh_HashState&
return Eh96_3.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 200 && k == 9) {
return Eh200_9.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 144 && k == 5) {
return Eh144_5.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 96 && k == 5) {
return Eh96_5.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 48 && k == 5) {
Expand All @@ -268,6 +276,8 @@ inline bool EhOptimisedSolveUncancellable(unsigned int n, unsigned int k, const
ret = Eh96_3.IsValidSolution(base_state, soln); \
} else if (n == 200 && k == 9) { \
ret = Eh200_9.IsValidSolution(base_state, soln); \
} else if (n == 144 && k == 5) { \
ret = Eh144_5.IsValidSolution(base_state, soln); \
} else if (n == 96 && k == 5) { \
ret = Eh96_5.IsValidSolution(base_state, soln); \
} else if (n == 48 && k == 5) { \
Expand All @@ -276,4 +286,24 @@ inline bool EhOptimisedSolveUncancellable(unsigned int n, unsigned int k, const
throw std::invalid_argument("Unsupported Equihash parameters"); \
}

inline unsigned int EhSolutionWidth(int n, int k)
{
unsigned int ret;
if (n == 96 && k == 3) {
ret = Eh96_3.SolutionWidth;
} else if (n == 200 && k == 9) {
ret = Eh200_9.SolutionWidth;
} else if (n == 144 && k == 5) {
ret = Eh144_5.SolutionWidth;
} else if (n == 96 && k == 5) {
ret = Eh96_5.SolutionWidth;
} else if (n == 48 && k == 5) {
ret = Eh48_5.SolutionWidth;
} else {
throw std::invalid_argument("Unsupported Equihash parameters");
}

return ret;
}

#endif // BITCOIN_EQUIHASH_H
29 changes: 24 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -3107,9 +3108,21 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f
REJECT_INVALID, "version-too-low");

// Check Equihash solution is valid
if (fCheckPOW && !CheckEquihashSolution(&block, Params()))
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),
REJECT_INVALID, "invalid-solution");
if (fCheckPOW) {
const CChainParams& chainparams = Params();

int oldSize = chainparams.EquihashSolutionWidth(chainparams.EquihashForkHeight());
int newSize = chainparams.EquihashSolutionWidth(chainparams.EquihashForkHeight() - 1);

if (block.nSolution.size() != oldSize && block.nSolution.size() != newSize)
return state.DoS(100, error("CheckBlockHeader(): Equihash solution has invalid size have %d need [%d, %d]",
block.nSolution.size(), oldSize, newSize),
REJECT_INVALID, "invalid-solution-size");

if (!CheckEquihashSolution(&block, chainparams))
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),
REJECT_INVALID, "invalid-solution");
}

// Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus()))
Expand Down Expand Up @@ -3199,7 +3212,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state,
return true;
}

bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev, bool fCheckPow)
{
const CChainParams& chainParams = Params();
const Consensus::Params& consensusParams = chainParams.GetConsensus();
Expand Down Expand Up @@ -3232,6 +3245,12 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
return state.Invalid(error("%s: block's timestamp is too early", __func__),
REJECT_INVALID, "time-too-old");

// Check that equihash solution has the proper length
if (fCheckPow && block.nSolution.size() != chainParams.EquihashSolutionWidth(nHeight))
return state.Invalid(error("%s: incorrect equihash solution size have %d need %d",
__func__, block.nSolution.size(), chainParams.EquihashSolutionWidth(nHeight)),
REJECT_INVALID, "equihash-solution-size");

if (fCheckpointsEnabled)
{
// Don't accept any forks from the main chain prior to last checkpoint
Expand Down Expand Up @@ -3546,7 +3565,7 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
auto verifier = libzcash::ProofVerifier::Disabled();

// NOTE: CheckBlockHeader is called by CheckBlock
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
if (!ContextualCheckBlockHeader(block, state, pindexPrev, fCheckPOW))
return false;

if (!CheckBlock(block, state, verifier, fCheckPOW, fCheckMerkleRoot))
Expand Down
3 changes: 2 additions & 1 deletion src/main.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -429,7 +430,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state,
bool fCheckPOW = true, bool fCheckMerkleRoot = true);

/** Context-dependent validity checks */
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev);
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev, bool fCheckPow = true);
bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev);

/** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */
Expand Down
8 changes: 6 additions & 2 deletions src/miner.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -692,8 +693,8 @@ void static BitcoinMiner()
// Each thread has its own counter
unsigned int nExtraNonce = 0;

unsigned int n = chainparams.EquihashN();
unsigned int k = chainparams.EquihashK();
unsigned int n;
unsigned int k;

std::string solver = GetArg("-equihashsolver", "default");
assert(solver == "tromp" || solver == "default");
Expand Down Expand Up @@ -740,6 +741,9 @@ void static BitcoinMiner()
//
unique_ptr<CBlockTemplate> pblocktemplate;

n = chainparams.EquihashN(pindexPrev->nHeight + 1);
k = chainparams.EquihashK(pindexPrev->nHeight + 1);

bool isNextBlockFork = isForkBlock(pindexPrev->nHeight+1);

if (isNextBlockFork) {
Expand Down
17 changes: 15 additions & 2 deletions src/pow.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -105,8 +106,20 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,

bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params)
{
unsigned int n = params.EquihashN();
unsigned int k = params.EquihashK();
uint64_t forkHeight = params.EquihashForkHeight();
unsigned int solution_size = pblock->nSolution.size();

unsigned int n;
unsigned int k;
if (solution_size == params.EquihashSolutionWidth(forkHeight)) {
n = params.EquihashN(forkHeight);
k = params.EquihashK(forkHeight);
} else if (forkHeight > 0 && solution_size == params.EquihashSolutionWidth(forkHeight - 1)) {
n = params.EquihashN(forkHeight - 1);
k = params.EquihashK(forkHeight - 1);
} else {
return error("CheckEquihashsolution(): invalid solution size");
}

// Hash state
crypto_generichash_blake2b_state state;
Expand Down
10 changes: 8 additions & 2 deletions src/rpcmining.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Bitcoin Private developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -202,10 +203,15 @@ UniValue generate(const UniValue& params, bool fHelp)
}
unsigned int nExtraNonce = 0;
UniValue blockHashes(UniValue::VARR);
unsigned int n = Params().EquihashN();
unsigned int k = Params().EquihashK();
const CChainParams& chainparams = Params();
unsigned int n;
unsigned int k;

while (nHeight < nHeightEnd)
{
n = chainparams.EquihashN(nHeight + 1);
k = chainparams.EquihashK(nHeight + 1);

#ifdef ENABLE_WALLET
std::unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
#else
Expand Down
Loading

0 comments on commit df4df2c

Please sign in to comment.