Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #315 from h4x3rotab/pow
Prepare for Equihash<144,5> PoW upgrade
  • Loading branch information
h4x3rotab committed Jun 4, 2018
2 parents 9e782b8 + 9fad3e4 commit 697f332
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 18 deletions.
25 changes: 24 additions & 1 deletion src/chainparams.cpp
@@ -1,5 +1,8 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Copyright (c) 2016-2017 The Zcash developers
// Copyright (c) 2018 The Bitcoin Private developers
// Copyright (c) 2017-2018 The Bitcoin Gold 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 @@ -101,6 +104,7 @@ class CMainParams : public CChainParams {
consensus.BTGHeight = 491407; // Around 10/25/2017 12:00 UTC
consensus.BTGPremineWindow = 8000;
consensus.BTGZawyLWMAHeight = std::numeric_limits<int>::max(); // Not activated on mainnet
consensus.BTGEquihashForkHeight = std::numeric_limits<int>::max(); // Not activated on mainnet
consensus.BTGPremineEnforceWhitelist = true;
consensus.powLimit = uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.powLimitStart = uint256S("0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
Expand Down Expand Up @@ -153,9 +157,13 @@ class CMainParams : public CChainParams {
nDefaultPort = 8338; // different port than Bitcoin
nPruneAfterHeight = 100000;
const size_t N = 200, K = 9;
const size_t N2 = 144, K2 = 5;
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K));
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N2, K2));
nEquihashN = N;
nEquihashK = K;
nEquihashNnew = N2;
nEquihashKnew = K2;

genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash(consensus);
Expand Down Expand Up @@ -231,6 +239,7 @@ class CTestNetParams : public CChainParams {
consensus.BIP66Height = -1;
consensus.BTGHeight = 1;
consensus.BTGZawyLWMAHeight = -1; // Activated on testnet
consensus.BTGEquihashForkHeight = std::numeric_limits<int>::max(); // Not activated on testnet
consensus.BTGPremineWindow = 50;
consensus.BTGPremineEnforceWhitelist = false;
consensus.powLimit = uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
Expand Down Expand Up @@ -278,10 +287,14 @@ class CTestNetParams : public CChainParams {
pchMessageStart[3] = 0x45;
nDefaultPort = 18338;
nPruneAfterHeight = 1000;
const size_t N = 200, K = 9; // Same as mainnet.
const size_t N = 200, K = 9;
const size_t N2 = 144, K2 = 5;
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K));
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N2, K2));
nEquihashN = N;
nEquihashK = K;
nEquihashNnew = N2;
nEquihashKnew = K2;

genesis = CreateGenesisBlock(1516123516, 0x56bd5142, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash(consensus);
Expand Down Expand Up @@ -336,6 +349,7 @@ class CRegTestParams : public CChainParams {
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
consensus.BTGHeight = 2000;
consensus.BTGZawyLWMAHeight = -1; // Activated on regtest
consensus.BTGEquihashForkHeight = 2001;
consensus.BTGPremineWindow = 10;
consensus.BTGPremineEnforceWhitelist = false;
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
Expand Down Expand Up @@ -380,9 +394,13 @@ class CRegTestParams : public CChainParams {
nDefaultPort = 18444;
nPruneAfterHeight = 1000;
const size_t N = 48, K = 5;
const size_t N2 = 96, K2 = 5;
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K));
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N2, K2));
nEquihashN = N;
nEquihashK = K;
nEquihashNnew = N2;
nEquihashKnew = K2;

genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash(consensus);
Expand Down Expand Up @@ -478,6 +496,11 @@ static CScript CltvMultiSigScript(const std::vector<std::string>& pubkeys, uint3
return redeem_script;
}

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

bool CChainParams::IsPremineAddressScript(const CScript& scriptPubKey, uint32_t height) const {
static const int LOCK_TIME = 3 * 365 * 24 * 3600; // 3 years
static const int LOCK_STAGES = 3 * 12; // Every month for 3 years
Expand Down
23 changes: 23 additions & 0 deletions src/chainparams.h
@@ -1,5 +1,8 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Copyright (c) 2016-2017 The Zcash developers
// Copyright (c) 2018 The Bitcoin Private developers
// Copyright (c) 2017-2018 The Bitcoin Gold 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 @@ -69,6 +72,24 @@ class CChainParams
uint64_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 >= consensus.BTGEquihashForkHeight) {
return nEquihashNnew;
} else {
return nEquihashN;
}
}
unsigned int EquihashK(int height) const
{
if(height >= consensus.BTGEquihashForkHeight) {
return nEquihashKnew;
} else {
return nEquihashK;
}
}
unsigned int EquihashSolutionWidth(int height) const;

/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
/** Return the BIP70 network string (main, test or regtest) */
Expand All @@ -90,6 +111,8 @@ class CChainParams
uint64_t nPruneAfterHeight;
unsigned int nEquihashN = 0;
unsigned int nEquihashK = 0;
unsigned int nEquihashNnew = 0;
unsigned int nEquihashKnew = 0;
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
std::string strNetworkID;
Expand Down
2 changes: 2 additions & 0 deletions src/consensus/params.h
Expand Up @@ -50,6 +50,8 @@ struct Params {
int BTGHeight;
/** Block height at which Zawy's LWMA difficulty algorithm becomes active */
int BTGZawyLWMAHeight;
/** Block height at which Equihash<144,5> becomes active */
int BTGEquihashForkHeight;
/** Limit BITCOIN_MAX_FUTURE_BLOCK_TIME **/
int64_t BTGMaxFutureBlockTime;
/** Premining blocks for Bitcoin GPU hard fork **/
Expand Down
12 changes: 12 additions & 0 deletions src/crypto/equihash.cpp
@@ -1,5 +1,7 @@
// Copyright (c) 2016 Jack Grigg
// Copyright (c) 2016 The Zcash developers
// Copyright (c) 2018 The Bitcoin Private developers
// Copyright (c) 2017-2018 The Bitcoin Gold 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 @@ -789,6 +791,16 @@ template bool Equihash<200,9>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(EhSolverCancelCheck)> cancelled);
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);
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);
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);
template bool Equihash<96,5>::BasicSolve(const eh_HashState& base_state,
Expand Down
30 changes: 30 additions & 0 deletions src/crypto/equihash.h
@@ -1,5 +1,7 @@
// Copyright (c) 2016 Jack Grigg
// Copyright (c) 2016 The Zcash developers
// Copyright (c) 2018 The Bitcoin Private developers
// Copyright (c) 2017-2018 The Bitcoin Gold 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 @@ -198,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 @@ -220,6 +225,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 @@ -244,6 +251,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 @@ -265,6 +274,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 @@ -273,4 +284,23 @@ 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
7 changes: 5 additions & 2 deletions src/pow.cpp
@@ -1,5 +1,8 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Copyright (c) 2016-2017 The Zcash developers
// Copyright (c) 2018 The Bitcoin Private developers
// Copyright (c) 2017-2018 The Bitcoin Gold 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 @@ -214,8 +217,8 @@ unsigned int BitcoinCalculateNextWorkRequired(const CBlockIndex* pindexLast, int

bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params)
{
unsigned int n = params.EquihashN();
unsigned int k = params.EquihashK();
unsigned int n = params.EquihashN(pblock->nHeight);
unsigned int k = params.EquihashK(pblock->nHeight);

// Hash state
crypto_generichash_blake2b_state state;
Expand Down
19 changes: 15 additions & 4 deletions src/rpc/mining.cpp
@@ -1,5 +1,8 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Copyright (c) 2016-2017 The Zcash developers
// Copyright (c) 2018 The Bitcoin Private developers
// Copyright (c) 2017-2018 The Bitcoin Gold 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 @@ -127,8 +130,8 @@ UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGen
unsigned int nExtraNonce = 0;
UniValue blockHashes(UniValue::VARR);
const CChainParams& params = Params();
unsigned int n = params.EquihashN();
unsigned int k = params.EquihashK();
unsigned int n;
unsigned int k;
while (nHeight < nHeightEnd)
{
std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(Params()).CreateNewBlock(coinbaseScript->reserveScript));
Expand All @@ -152,6 +155,8 @@ UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGen
// Solve Equihash.
nInnerLoopMask = nInnerLoopEquihashMask;
nInnerLoopCount = nInnerLoopEquihashCount;
n = params.EquihashN(pblock->nHeight);
k = params.EquihashK(pblock->nHeight);
crypto_generichash_blake2b_state eh_state;
EhInitialiseState(n, k, eh_state);

Expand Down Expand Up @@ -421,6 +426,8 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
" \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
" \"bits\" : \"xxxxxxxx\", (string) compressed target of next block\n"
" \"height\" : n (numeric) The height of the next block\n"
" \"equihashn\" : n (numeric) Equihash N\n"
" \"equihashk\" : n (numeric) Equihash K\n"
"}\n"

"\nExamples:\n"
Expand Down Expand Up @@ -592,7 +599,8 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
pindexPrev = pindexPrevNew;
}
CBlock* pblock = &pblocktemplate->block; // pointer for convenience
const Consensus::Params& consensusParams = Params().GetConsensus();
const CChainParams& params = Params();
const Consensus::Params& consensusParams = params.GetConsensus();

// Update nTime
UpdateTime(pblock, consensusParams, pindexPrev);
Expand Down Expand Up @@ -734,7 +742,10 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
}
result.push_back(Pair("curtime", pblock->GetBlockTime()));
result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
int height = pindexPrev->nHeight + 1;
result.push_back(Pair("height", (int64_t)height));
result.push_back(Pair("equihashn", (int64_t)(params.EquihashN(height))));
result.push_back(Pair("equihashk", (int64_t)(params.EquihashK(height))));

if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) {
result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end())));
Expand Down
18 changes: 14 additions & 4 deletions src/validation.cpp
Expand Up @@ -2796,10 +2796,20 @@ static bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state,
{
// Check Equihash solution is valid
bool postfork = block.nHeight >= (uint32_t)consensusParams.BTGHeight;
if (fCheckPOW && postfork && !CheckEquihashSolution(&block, Params())) {
LogPrintf("CheckBlockHeader(): Equihash solution invalid at height %d\n", block.nHeight);
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),
REJECT_INVALID, "invalid-solution");
if (fCheckPOW && postfork) {
const CChainParams& chainparams = Params();
const int sol_size = chainparams.EquihashSolutionWidth(block.nHeight);
if(block.nSolution.size() != sol_size) {
return state.DoS(
100, error("CheckBlockHeader(): Equihash solution has invalid size have %d need %d",
block.nSolution.size(), sol_size),
REJECT_INVALID, "invalid-solution-size");
}
if (!CheckEquihashSolution(&block, Params())) {
LogPrintf("CheckBlockHeader(): Equihash solution invalid at height %d\n", block.nHeight);
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),
REJECT_INVALID, "invalid-solution");
}
}

// Check proof of work matches claimed amount
Expand Down
22 changes: 16 additions & 6 deletions test/functional/btg-hardfork.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Copyright (c) 2017-2018 The Bitcoin Gold developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test cases for Bitcoin Gold fork """
Expand All @@ -19,16 +20,25 @@ def run_test(self):
node = self.nodes[0]

# Basic block generation test.
# Block #2999.
self.log.info("Generating 2799 blocks.")
node.generate(2799)
# Block #1999.
self.log.info("Generating 1799 blocks.")
node.generate(1799)
tmpl = node.getblocktemplate()
assert_equal(tmpl['height'], 3000)
assert_equal(tmpl['height'], 2000)
assert_equal(tmpl['equihashn'], 48)
assert_equal(tmpl['equihashk'], 5)

# Block #3000, Equihash enabled.
# Block #2000, Equihash<48,5> enabled.
node.generate(1)
tmpl = node.getblocktemplate()
assert_equal(tmpl['height'], 3001)
assert_equal(tmpl['height'], 2001)
assert_equal(tmpl['equihashn'], 96)
assert_equal(tmpl['equihashk'], 5)

# Block #2001, Equihash<96,5> enabled.
node.generate(1)
tmpl = node.getblocktemplate()
assert_equal(tmpl['height'], 2002)


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion test/functional/test_framework/mininode.py
Expand Up @@ -54,7 +54,7 @@
NODE_UNSUPPORTED_SERVICE_BIT_5 = (1 << 5)
NODE_UNSUPPORTED_SERVICE_BIT_7 = (1 << 7)

BTG_REGTEST_HARDFORK_HEIGHT = 3000
BTG_REGTEST_HARDFORK_HEIGHT = 2000

logger = logging.getLogger("TestFramework.mininode")

Expand Down

0 comments on commit 697f332

Please sign in to comment.