diff --git a/README.md b/README.md index 6f30f1e54b..6ad4c12af1 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,22 @@ [![Build Status](https://travis-ci.org/BTCGPU/BTCGPU.svg?branch=master)](https://travis-ci.org/BTCGPU/BTCGPU) -Bitcoin Gold (codename BTCGPU) is a fork of the Bitcoin blockchain that will occur at block height 491407, at roughly 12:00:00 UTC October 25, 2017. +Bitcoin Gold (codename BTCGPU) began as a fork of Bitcoin after block height 491406 on Tue, 24 Oct 2017 01:17:35 GMT and began being mined as a separate chain at block height 491407 on Sun, 12 Nov 2017 13:34:01 GMT. -At the predetermined block height, Bitcoin Gold miners will begin creating blocks with a new proof-of-work algorithm, and this will cause a bifurcation of the Bitcoin blockchain. The original Bitcoin blockchain will continue on unaltered, but a new branch of the blockchain will split off from the original chain. The new branch is a distinct blockchain with the same transaction history as Bitcoin up until the fork, but then diverges from it. As a result of this process, a new cryptocurrency will be born. +The primary goal is to maintain a variant of Bitcoin that is more decentralized by using an ASIC-resistant Proof of Work algorithm, removing barriers to entry for new miners around the world and reducing the concentration of power in the hands of massive-scale mining operations. + +Bitcoin Gold preserves and implements Bitcoin features such as SegWit. Significant differences at launch time included: + +- ASIC-resistant GPU-minable PoW algorithm (Equihash) +- Per-block difficulty adjustment algorithm +- Replay protection (SIGHASH_FORK_ID) +- Unique wallet addresses (prefixes of G and A) + +Although BTG was bootstrapped on 12 Nov to create an entirely new network, it contains the entire Bitcoin blockchain until block 491406. As a result, Bitcoin Gold became a full fork with all Bitcoin transaction history since 2009. Any Bitcoin wallet address which held Bitcoin in BTC block 491406 before the fork held an equal number of Bitcoin Gold in BTG block 491407 after the fork. ## Links * Website: https://bitcoingold.org * Tech Spec: https://github.com/BTCGPU/BTCGPU/wiki/Technical-Spec -* Slack: [invitation](https://join.slack.com/t/bitcoin-gold/shared_invite/enQtMjY1MzkzMzUxNjY4LWM1YmQ4MjZhZTQxMWE1ZDQyNjA4N2QwZTkyZjYzMjhiMzdlMmVkNjQ3NzZlZDdmMDE4NWIyY2JmYzdjYmE2MzA) +* Forum: https://forum.bitcoingold.org +* Discord: [invitation](https://discord.gg/HmVUU6S) diff --git a/configure.ac b/configure.ac index dd791769fa..c5b098744e 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 15) -define(_CLIENT_VERSION_REVISION, 0) -define(_CLIENT_VERSION_BUILD, 2) +define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2018) define(_COPYRIGHT_HOLDERS,[The %s developers]) @@ -727,12 +727,12 @@ AC_CHECK_LIB(sodium, sodium_init,[], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #include ], [ -#if SODIUM_LIBRARY_VERSION_MAJOR < 9 || SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR < 5 +#if SODIUM_LIBRARY_VERSION_MAJOR < 9 || SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR < 1 # error #endif ])], [AC_MSG_RESULT([checking for version of libsodium... yes])], -[AC_MSG_ERROR([Wrong libsodium: version >= 1.0.13 required])]) +[AC_MSG_ERROR([Wrong libsodium: version >= 1.0.8 required])]) BITCOIN_QT_INIT diff --git a/contrib/gitian-build.sh b/contrib/gitian-build.sh index 3c0fd80975..d54e8e9e1c 100755 --- a/contrib/gitian-build.sh +++ b/contrib/gitian-build.sh @@ -307,7 +307,7 @@ then # Linux if [[ $linux = true ]] then - echo "" + echo "" echo "Compiling ${VERSION} Linux" echo "" ./bin/gbuild -j ${proc} -m ${mem} --commit BTCGPU=${COMMIT} --url BTCGPU=${url} ../BTCGPU/contrib/gitian-descriptors/gitian-linux.yml @@ -317,6 +317,26 @@ then # Windows if [[ $windows = true ]] then + if [ ! -f inputs/nsis-win32-utils.zip ]; + then + echo "" + echo "Starting Utilities build for Windows" + echo "" + ./bin/gbuild -j ${proc} -m ${mem} --allow-sudo ../BTCGPU/contrib/gitian-descriptors/gitian-win-utils.yml + if [ $? -ne 0 ]; + then + echo "" + echo "FAILED to build Utilities for Windows" + echo "" + exit 1 + fi + + cd inputs + cp -a ../build/out/*-utils.zip . + mv nsis-*-win32-utils.zip nsis-win32-utils.zip + cd .. + fi + echo "" echo "Compiling ${VERSION} Windows" echo "" diff --git a/contrib/gitian-descriptors/gitian-win-utils.yml b/contrib/gitian-descriptors/gitian-win-utils.yml new file mode 100644 index 0000000000..e934587346 --- /dev/null +++ b/contrib/gitian-descriptors/gitian-win-utils.yml @@ -0,0 +1,97 @@ +--- +name: "utils-windows" +sudo: true +suites: +- "trusty" +architectures: +- "amd64" +packages: +- "libtool" +- "automake" +- "libfaketime" +- "mingw-w64" +- "g++-mingw-w64" +- "zip" +- "unzip" +# Needed for compiling nsis. +- "scons" +- "libcppunit-dev" +- "zlib1g" +- "zlib1g-dev" +reference_datetime: "2016-01-01 00:00:00" +remotes: [] +files: [] +script: | + WRAP_DIR="$HOME/wrapped" + INSTDIR="$HOME/install" + + NSIS_VER=3.03 + NSIS_PACKAGE=nsis-${NSIS_VER}-src.tar.bz2 + NSIS_DEBIAN_PACKAGE=nsis_${NSIS_VER}-2.debian.tar.xz + NSIS_HASH=abae7f4488bc6de7a4dd760d5f0e7cd3aad7747d4d7cd85786697c8991695eaa + NSIS_DEBIAN_HASH=b12956c561d7ad2e078561684a8a06c95c583c14c4d904ec93d252e2d2c2d75c + NSIS_URL=http://downloads.sourceforge.net/nsis/${NSIS_PACKAGE} + NSIS_DEBIAN_URL=http://http.debian.net/debian/pool/main/n/nsis/${NSIS_DEBIAN_PACKAGE} + + echo "${REFERENCE_DATETIME}" | sudo tee --append /etc/faketimerc + echo "/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1" | sudo tee --append /etc/ld.so.preload + + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + + get() { + local file="$1"; shift + local url="$1"; shift + + if ! wget --no-check-certificate -U "" -N "$url"; then + echo >&2 "Error: Cannot download $url" + mv "${file}" "${file}.DLFAILED" + exit 1 + fi + } + + dzip() { + export LC_ALL=C + + ZIPFILE=${1:?} + shift + + if [ -n "$REFERENCE_DATETIME" ]; then + find "$@" -exec touch --date="$REFERENCE_DATETIME" -- {} + + fi + find "$@" -executable -exec chmod 700 {} + + find "$@" ! -executable -exec chmod 600 {} + + find "$@" | sort | zip $ZIPOPTS -X -@ "$ZIPFILE" + } + + for i in NSIS NSIS_DEBIAN + do + URL="${i}_URL" + PACKAGE="${i}_PACKAGE" + get "${!PACKAGE}" "${!URL}" + + HASH="${i}_HASH" + if ! echo "${!HASH} ${!PACKAGE}" | sha256sum -c -; then + echo "Package hash for ${!PACKAGE} differs from our locally stored sha256!" + exit 1 + fi + done + + get Zlib-1.2.7-win32-x86.zip http://nsis.sourceforge.net/mediawiki/images/c/ca/Zlib-1.2.7-win32-x86.zip + unzip -d Zlib-1.2.7 Zlib-1.2.7-win32-x86.zip + + # Building nsis + tar xf $NSIS_PACKAGE + cd nsis-${NSIS_VER}-src + tar xf ../$NSIS_DEBIAN_PACKAGE + scons VERSION=${NSIS_VER} SKIPUTILS='NSIS Menu' XGCC_W32_PREFIX=i686-w64-mingw32- ZLIB_W32=${HOME}/build/Zlib-1.2.7 PREFIX=$INSTDIR/nsis + scons VERSION=${NSIS_VER} SKIPUTILS='NSIS Menu' XGCC_W32_PREFIX=i686-w64-mingw32- ZLIB_W32=${HOME}/build/Zlib-1.2.7 PREFIX=$INSTDIR/nsis install + cd .. + + # Grabbing the remaining results + cd $INSTDIR + dzip nsis-$NSIS_VER-win32-utils.zip nsis + cp nsis-$NSIS_VER-win32-utils.zip $OUTDIR/ diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 5b7c63142d..a8eb906cc0 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -17,14 +17,15 @@ packages: - "bsdmainutils" - "mingw-w64" - "g++-mingw-w64" -- "nsis" - "zip" +- "unzip" - "ca-certificates" - "python" remotes: - "url": "https://github.com/BTCGPU/BTCGPU.git" "dir": "BTCGPU" -files: [] +files: +- "nsis-win32-utils.zip" script: | WRAP_DIR=$HOME/wrapped HOSTS="i686-w64-mingw32 x86_64-w64-mingw32" @@ -94,6 +95,10 @@ script: | done } + # Extract nsis + unzip -d $HOME/install ${BUILD_DIR}/nsis-win32-utils.zip + export PATH=$HOME/install/nsis/bin:$PATH + # Faketime for depends so intermediate results are comparable export PATH_orig=${PATH} create_global_faketime_wrappers "2000-01-01 12:00:00" diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh index b01e2a6d39..930fcf6c38 100755 --- a/contrib/verify-commits/gpg.sh +++ b/contrib/verify-commits/gpg.sh @@ -52,7 +52,7 @@ if ! $VALID; then exit 1 fi if $VALID && $REVSIG; then - echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null | grep "\[GNUPG:\] \(NEWSIG\|SIG_ID\|VALIDSIG\)" + echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null | grep "^\[GNUPG:\] \(NEWSIG\|SIG_ID\|VALIDSIG\)" echo "$GOODREVSIG" else echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null diff --git a/doc/build-unix.md b/doc/build-unix.md index c73ecf45ea..5ba28db67d 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -104,6 +104,23 @@ ZMQ dependencies (provides ZMQ API 4.x): sudo apt-get install libzmq3-dev +3. On Ubuntu 16.04.3 you need to install the newest libsodium (at least 1.0.13) + + configure: error: Wrong libsodium: version >= 1.0.13 required + +I tested it with version 1.0.15 (from the `depends` directory) at it works. + + $ cd BTCGPU + $ cd depends + $ make + $ cd .. + $ ./autogen.sh + $ ./configure --prefix=`pwd`/depends/x86_64-pc-linux-gnu + $ make + $ make install + +The command `make install` installs the executables in the `./depends/x86_64-pc-linux-gnu/bin/` directory. + Dependencies for the GUI: Ubuntu & Debian ----------------------------------------- diff --git a/src/chain.h b/src/chain.h index 2dc9e7f7fe..367eb5a6a3 100644 --- a/src/chain.h +++ b/src/chain.h @@ -19,15 +19,15 @@ * Maximum amount of time that a block timestamp is allowed to exceed the * current network-adjusted time before the block will be accepted. */ -static const int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; +static const int64_t BITCOIN_MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; /** * Timestamp window used as a grace period by code that compares external * timestamps (such as timestamps passed to RPCs, or wallet key creation times) * to block timestamps. This should be set at least as high as - * MAX_FUTURE_BLOCK_TIME. + * BITCOIN_MAX_FUTURE_BLOCK_TIME. */ -static const int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; +static const int64_t TIMESTAMP_WINDOW = BITCOIN_MAX_FUTURE_BLOCK_TIME; class CBlockFileInfo { diff --git a/src/chainparams.cpp b/src/chainparams.cpp index ee8614b322..ce3bfbece3 100644 --- a/src/chainparams.cpp +++ b/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. @@ -24,6 +27,7 @@ #include "base58.h" #include #include +#include #include "chainparamsseeds.h" @@ -46,6 +50,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi genesis.hashPrevBlock.SetNull(); genesis.nHeight = 0; genesis.hashMerkleRoot = BlockMerkleRoot(genesis); + return genesis; } @@ -98,18 +103,27 @@ class CMainParams : public CChainParams { consensus.BIP66Height = 363725; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 consensus.BTGHeight = 491407; // Around 10/25/2017 12:00 UTC consensus.BTGPremineWindow = 8000; + consensus.BTGZawyLWMAHeight = 536200; // Around 07/01/2018 + consensus.BTGEquihashForkHeight = 536200; // Around 07/01/2018 consensus.BTGPremineEnforceWhitelist = true; consensus.powLimit = uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.powLimitStart = uint256S("0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.powLimitLegacy = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + + consensus.nDigishieldAveragingWindow = 30; + assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nDigishieldAveragingWindow); + consensus.nDigishieldMaxAdjustDown = 32; + consensus.nDigishieldMaxAdjustUp = 16; + + consensus.nZawyLwmaAveragingWindow = 45; + consensus.nZawyLwmaAdjustedWeightLegacy = 13772; + consensus.nZawyLwmaAdjustedWeight = 13772; + consensus.nZawyLwmaMinDenominatorLegacy = 10; + consensus.nZawyLwmaMinDenominator = 10; + consensus.bZawyLwmaSolvetimeLimitation = true; + consensus.BTGMaxFutureBlockTime = 12 * 10 * 60; // 120 mins - //based on https://github.com/BTCGPU/BTCGPU/issues/78 - consensus.nPowAveragingWindow = 30; - assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); - consensus.nPowMaxAdjustDown = 32; - consensus.nPowMaxAdjustUp = 16; - - consensus.nPowTargetTimespanLegacy = 14 * 24 * 60 * 60;; // 10 minutes + consensus.nPowTargetTimespanLegacy = 14 * 24 * 60 * 60; // 10 minutes consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = false; consensus.fPowNoRetargeting = false; @@ -147,9 +161,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); @@ -219,22 +237,31 @@ class CTestNetParams : public CChainParams { CTestNetParams() { strNetworkID = "test"; consensus.nSubsidyHalvingInterval = 210000; - consensus.BIP34Height = 21111; - consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8"); - consensus.BIP65Height = 581885; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 - consensus.BIP66Height = 330776; // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 - consensus.BTGHeight = 1210320; + consensus.BIP34Height = -1; + consensus.BIP34Hash = uint256(); + consensus.BIP65Height = -1; + consensus.BIP66Height = -1; + consensus.BTGHeight = 1; + consensus.BTGZawyLWMAHeight = -1; // Activated on testnet + consensus.BTGEquihashForkHeight = 14300; consensus.BTGPremineWindow = 50; consensus.BTGPremineEnforceWhitelist = false; consensus.powLimit = uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.powLimitStart = uint256S("0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.powLimitStart = uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.powLimitLegacy = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - //based on https://github.com/BTCGPU/BTCGPU/issues/78 - consensus.nPowAveragingWindow = 30; - assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); - consensus.nPowMaxAdjustDown = 32; - consensus.nPowMaxAdjustUp = 16; + consensus.nDigishieldAveragingWindow = 30; + assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nDigishieldAveragingWindow); + consensus.nDigishieldMaxAdjustDown = 32; + consensus.nDigishieldMaxAdjustUp = 16; + + consensus.nZawyLwmaAveragingWindow = 45; + consensus.nZawyLwmaAdjustedWeightLegacy = 13632; + consensus.nZawyLwmaAdjustedWeight = 13772; + consensus.nZawyLwmaMinDenominatorLegacy = 3; + consensus.nZawyLwmaMinDenominator = 10; + consensus.bZawyLwmaSolvetimeLimitation = false; + consensus.BTGMaxFutureBlockTime = 7 * 10 * 60; // 70 mins consensus.nPowTargetTimespanLegacy = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetSpacing = 10 * 60; @@ -248,36 +275,39 @@ class CTestNetParams : public CChainParams { // Deployment of BIP68, BIP112, and BIP113. consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016 - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017 + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1514764800; // January 1st, 2018 + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1546300800; // January 1st, 2019 // Deployment of SegWit (BIP141, BIP143, and BIP147) consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016 - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1514764800; // January 1st 2018 + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1546300800; // January 1st 2019 // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000002830dab7f76dbb7d63"); + consensus.nMinimumChainWork = uint256S("0x00"); // By default assume that the signatures in ancestors of this block are valid. - consensus.defaultAssumeValid = uint256S("0x0000000002e9e7b00e1f6dc5123a04aad68dd0f0968d8c7aa45f6640795c37b1"); //1135275 + consensus.defaultAssumeValid = uint256S("0x00"); - pchMessageStart[0] = 0xe1; + pchMessageStart[0] = 0xe2; pchMessageStart[1] = 0x48; pchMessageStart[2] = 0x6e; pchMessageStart[3] = 0x45; nDefaultPort = 18338; nPruneAfterHeight = 1000; - const size_t N = 200, K = 9; // Same as mainchain. + 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(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN); + genesis = CreateGenesisBlock(1516123516, 0x56bd5142, 0x1d00ffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(consensus); - assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); + assert(consensus.hashGenesisBlock == uint256S("0x00000000e0781ebe24b91eedc293adfea2f557b53ec379e78959de3853e6f9f6")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - vFixedSeeds.clear(); vSeeds.clear(); // nodes with support for servicebits filtering should be at the top @@ -285,7 +315,6 @@ class CTestNetParams : public CChainParams { vSeeds.emplace_back("eu-test-dnsseed.bitcoingold-official.org", true); vSeeds.emplace_back("test-dnsseed.bitcoingold.org", true); vSeeds.emplace_back("test-dnsseed.btcgpu.org", true); - vSeeds.emplace_back("btg.dnsseed.minertopia.org", true); base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); @@ -302,15 +331,14 @@ class CTestNetParams : public CChainParams { checkpointData = (CCheckpointData) { { - {546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, + {0, uint256S("0x00000000e0781ebe24b91eedc293adfea2f557b53ec379e78959de3853e6f9f6")}, } }; chainTxData = ChainTxData{ - // Data as of block 00000000000001c200b9790dc637d3bb141fe77d155b966ed775b17e109f7c6c (height 1156179) - 1501802953, - 14706531, - 0.15 + 0, + 0, + 0 }; } }; @@ -327,16 +355,27 @@ class CRegTestParams : public CChainParams { consensus.BIP34Hash = uint256(); consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests) consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests) - consensus.BTGHeight = 3000; + consensus.BTGHeight = 2000; + consensus.BTGZawyLWMAHeight = -1; // Activated on regtest + consensus.BTGEquihashForkHeight = 2001; consensus.BTGPremineWindow = 10; consensus.BTGPremineEnforceWhitelist = false; consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.powLimitStart = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.powLimitLegacy = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - //based on https://github.com/BTCGPU/BTCGPU/issues/78 - consensus.nPowAveragingWindow = 30; - consensus.nPowMaxAdjustDown = 16; - consensus.nPowMaxAdjustUp = 32; + + consensus.nDigishieldAveragingWindow = 30; + consensus.nDigishieldMaxAdjustDown = 32; + consensus.nDigishieldMaxAdjustUp = 16; + + consensus.nZawyLwmaAveragingWindow = 45; + consensus.nZawyLwmaAdjustedWeightLegacy = 13772; + consensus.nZawyLwmaAdjustedWeight = 13772; + consensus.nZawyLwmaMinDenominatorLegacy = 10; + consensus.nZawyLwmaMinDenominator = 10; + consensus.bZawyLwmaSolvetimeLimitation = true; + consensus.BTGMaxFutureBlockTime = 7 * 10 * 60; // 70 mins + consensus.nPowTargetTimespanLegacy = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; @@ -367,9 +406,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); @@ -465,6 +508,11 @@ static CScript CltvMultiSigScript(const std::vector& 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 diff --git a/src/chainparams.h b/src/chainparams.h index 0cb1dd50c2..a431a8a0c4 100644 --- a/src/chainparams.h +++ b/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. @@ -69,6 +72,28 @@ 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; + } + } + bool EquihashUseBTGSalt(int height) const + { + return height >= consensus.BTGEquihashForkHeight; + } + 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) */ @@ -90,6 +115,8 @@ class CChainParams uint64_t nPruneAfterHeight; unsigned int nEquihashN = 0; unsigned int nEquihashK = 0; + unsigned int nEquihashNnew = 0; + unsigned int nEquihashKnew = 0; std::vector vSeeds; std::vector base58Prefixes[MAX_BASE58_TYPES]; std::string strNetworkID; diff --git a/src/consensus/params.h b/src/consensus/params.h index 56fe77b698..995ff88b9e 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -48,6 +48,12 @@ struct Params { int BIP66Height; /** Block height at which Bitcoin GPU hard fork becomes active */ 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 **/ int BTGPremineWindow; bool BTGPremineEnforceWhitelist; @@ -73,15 +79,38 @@ struct Params { uint256 nMinimumChainWork; uint256 defaultAssumeValid; - //Zcash logic for diff adjustment - int64_t nPowAveragingWindow; - int64_t nPowMaxAdjustDown; - int64_t nPowMaxAdjustUp; - int64_t AveragingWindowTimespan() const { return nPowAveragingWindow * nPowTargetSpacing; } - int64_t MinActualTimespan() const { return (AveragingWindowTimespan() * (100 - nPowMaxAdjustUp )) / 100; } - int64_t MaxActualTimespan() const { return (AveragingWindowTimespan() * (100 + nPowMaxAdjustDown)) / 100; } - - + // Params for Digishield difficulty adjustment algorithm. (Used by mainnet currently.) + int64_t nDigishieldAveragingWindow; + int64_t nDigishieldMaxAdjustDown; + int64_t nDigishieldMaxAdjustUp; + int64_t DigishieldAveragingWindowTimespan() const { return nDigishieldAveragingWindow * nPowTargetSpacing; } + int64_t DigishieldMinActualTimespan() const { + return (DigishieldAveragingWindowTimespan() * (100 - nDigishieldMaxAdjustUp)) / 100; + } + int64_t DigishieldMaxActualTimespan() const { + return (DigishieldAveragingWindowTimespan() * (100 + nDigishieldMaxAdjustDown)) / 100; + } + + // Params for Zawy's LWMA difficulty adjustment algorithm. + int64_t nZawyLwmaAveragingWindow; + int64_t nZawyLwmaAdjustedWeight; // k = (N+1)/2 * 0.998 * T + int64_t nZawyLwmaMinDenominator; + bool bZawyLwmaSolvetimeLimitation; + + // Legacy params for Zawy's LWMA before the PoW fork. Only used by testnet + int64_t nZawyLwmaAdjustedWeightLegacy; // k = (N+1)/2 * 0.9989^(500/N) * T + int64_t nZawyLwmaMinDenominatorLegacy; + + int64_t ZawyLwmaAdjustedWeight(int height) const { + return (height >= BTGEquihashForkHeight) + ? nZawyLwmaAdjustedWeight + : nZawyLwmaAdjustedWeightLegacy; + } + int64_t ZawyLwmaMinDenominator(int height) const { + return (height >= BTGEquihashForkHeight) + ? nZawyLwmaMinDenominator + : nZawyLwmaMinDenominatorLegacy; + } }; } // namespace Consensus diff --git a/src/crypto/common.h b/src/crypto/common.h index b321dfceaa..4dfc070492 100644 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -108,8 +108,6 @@ int inline init_and_check_sodium() return -1; } - // What follows is a runtime test that ensures the version of libsodium - // we're linked against checks that signatures are canonical (s < L). const unsigned char message[1] = { 0 }; unsigned char pk[crypto_sign_PUBLICKEYBYTES]; @@ -120,23 +118,6 @@ int inline init_and_check_sodium() crypto_sign_detached(sig, NULL, message, sizeof(message), sk); assert(crypto_sign_verify_detached(sig, message, sizeof(message), pk) == 0); - - // Copied from libsodium/crypto_sign/ed25519/ref10/open.c - static const unsigned char L[32] = { - 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, - 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; - - // Add L to S, which starts at sig[32]. - unsigned int s = 0; - for (size_t i = 0; i < 32; i++) { - s = sig[32 + i] + L[i] + (s >> 8); - sig[32 + i] = s & 0xff; - } - - assert(crypto_sign_verify_detached(sig, message, sizeof(message), pk) != 0); - return 0; } diff --git a/src/crypto/equihash.cpp b/src/crypto/equihash.cpp index ead0df8bc8..b08d109875 100644 --- a/src/crypto/equihash.cpp +++ b/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. @@ -33,12 +35,16 @@ EhSolverCancelledException solver_cancelled; template -int Equihash::InitialiseState(eh_HashState& base_state) +int Equihash::InitialiseState(eh_HashState& base_state, bool btg_salt) { uint32_t le_N = htole32(N); uint32_t le_K = htole32(K); unsigned char personalization[crypto_generichash_blake2b_PERSONALBYTES] = {}; - memcpy(personalization, "ZcashPoW", 8); + if (btg_salt) { + memcpy(personalization, "BgoldPoW", 8); + } else { + memcpy(personalization, "ZcashPoW", 8); + } memcpy(personalization+8, &le_N, 4); memcpy(personalization+12, &le_K, 4); return crypto_generichash_blake2b_init_salt_personal(&base_state, @@ -770,7 +776,7 @@ bool Equihash::IsValidSolution(const eh_HashState& base_state, std::vector< } // Explicit instantiations for Equihash<96,3> -template int Equihash<96,3>::InitialiseState(eh_HashState& base_state); +template int Equihash<96,3>::InitialiseState(eh_HashState& base_state, bool btg_salt); template bool Equihash<96,3>::BasicSolve(const eh_HashState& base_state, const std::function)> validBlock, const std::function cancelled); @@ -780,7 +786,7 @@ template bool Equihash<96,3>::OptimisedSolve(const eh_HashState& base_state, template bool Equihash<96,3>::IsValidSolution(const eh_HashState& base_state, std::vector soln); // Explicit instantiations for Equihash<200,9> -template int Equihash<200,9>::InitialiseState(eh_HashState& base_state); +template int Equihash<200,9>::InitialiseState(eh_HashState& base_state, bool btg_salt); template bool Equihash<200,9>::BasicSolve(const eh_HashState& base_state, const std::function)> validBlock, const std::function cancelled); @@ -789,8 +795,18 @@ template bool Equihash<200,9>::OptimisedSolve(const eh_HashState& base_state, const std::function cancelled); template bool Equihash<200,9>::IsValidSolution(const eh_HashState& base_state, std::vector soln); +// Explicit instantiations for Equihash<144,5> +template int Equihash<144,5>::InitialiseState(eh_HashState& base_state, bool btg_salt); +template bool Equihash<144,5>::BasicSolve(const eh_HashState& base_state, + const std::function)> validBlock, + const std::function cancelled); +template bool Equihash<144,5>::OptimisedSolve(const eh_HashState& base_state, + const std::function)> validBlock, + const std::function cancelled); +template bool Equihash<144,5>::IsValidSolution(const eh_HashState& base_state, std::vector soln); + // Explicit instantiations for Equihash<96,5> -template int Equihash<96,5>::InitialiseState(eh_HashState& base_state); +template int Equihash<96,5>::InitialiseState(eh_HashState& base_state, bool btg_salt); template bool Equihash<96,5>::BasicSolve(const eh_HashState& base_state, const std::function)> validBlock, const std::function cancelled); @@ -800,7 +816,7 @@ template bool Equihash<96,5>::OptimisedSolve(const eh_HashState& base_state, template bool Equihash<96,5>::IsValidSolution(const eh_HashState& base_state, std::vector soln); // Explicit instantiations for Equihash<48,5> -template int Equihash<48,5>::InitialiseState(eh_HashState& base_state); +template int Equihash<48,5>::InitialiseState(eh_HashState& base_state, bool btg_salt); template bool Equihash<48,5>::BasicSolve(const eh_HashState& base_state, const std::function)> validBlock, const std::function cancelled); diff --git a/src/crypto/equihash.h b/src/crypto/equihash.h index 85058e2fd0..e1695408ad 100644 --- a/src/crypto/equihash.h +++ b/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. @@ -182,7 +184,7 @@ class Equihash Equihash() { } - int InitialiseState(eh_HashState& base_state); + int InitialiseState(eh_HashState& base_state, bool btg_salt); bool BasicSolve(const eh_HashState& base_state, const std::function)> validBlock, const std::function cancelled); @@ -198,17 +200,20 @@ static Equihash<96,3> Eh96_3; static Equihash<200,9> Eh200_9; static Equihash<96,5> Eh96_5; static Equihash<48,5> Eh48_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 == 96 && k == 5) { \ - Eh96_5.InitialiseState(base_state); \ - } else if (n == 48 && k == 5) { \ - Eh48_5.InitialiseState(base_state); \ - } else { \ +static Equihash<144,5> Eh144_5; + +#define EhInitialiseState(n, k, base_state, btg_salt) \ + if (n == 96 && k == 3) { \ + Eh96_3.InitialiseState(base_state, btg_salt); \ + } else if (n == 200 && k == 9) { \ + Eh200_9.InitialiseState(base_state, btg_salt); \ + } else if (n == 144 && k == 5) { \ + Eh144_5.InitialiseState(base_state, btg_salt); \ + } else if (n == 96 && k == 5) { \ + Eh96_5.InitialiseState(base_state, btg_salt); \ + } else if (n == 48 && k == 5) { \ + Eh48_5.InitialiseState(base_state, btg_salt); \ + } else { \ throw std::invalid_argument("Unsupported Equihash parameters"); \ } @@ -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) { @@ -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) { @@ -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) { \ @@ -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 diff --git a/src/miner.h b/src/miner.h index 5c9cfd78f0..c7360c10f9 100644 --- a/src/miner.h +++ b/src/miner.h @@ -71,7 +71,7 @@ struct modifiedentry_iter { // except operating on CTxMemPoolModifiedEntry. // TODO: refactor to avoid duplication of this logic. struct CompareModifiedEntry { - bool operator()(const CTxMemPoolModifiedEntry &a, const CTxMemPoolModifiedEntry &b) + bool operator()(const CTxMemPoolModifiedEntry &a, const CTxMemPoolModifiedEntry &b) const { double f1 = (double)a.nModFeesWithAncestors * b.nSizeWithAncestors; double f2 = (double)b.nModFeesWithAncestors * a.nSizeWithAncestors; @@ -86,7 +86,7 @@ struct CompareModifiedEntry { // This is sufficient to sort an ancestor package in an order that is valid // to appear in a block. struct CompareTxIterByAncestorCount { - bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) + bool operator()(const CTxMemPool::txiter &a, const CTxMemPool::txiter &b) const { if (a->GetCountWithAncestors() != b->GetCountWithAncestors()) return a->GetCountWithAncestors() < b->GetCountWithAncestors(); diff --git a/src/pow.cpp b/src/pow.cpp index bb2772b42f..4f1e9ce9ec 100644 --- a/src/pow.cpp +++ b/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. @@ -14,26 +17,120 @@ #include "uint256.h" #include "util.h" -unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) +#include +#include + +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, + const Consensus::Params& params) { assert(pindexLast != nullptr); int nHeight = pindexLast->nHeight + 1; bool postfork = nHeight >= params.BTGHeight; - unsigned int nProofOfWorkLimit = UintToArith256(params.PowLimit(postfork)).GetCompact(); if (postfork == false) { + // Original Bitcion PoW. return BitcoinGetNextWorkRequired(pindexLast, pblock, params); } else if (nHeight < params.BTGHeight + params.BTGPremineWindow) { + // PoW limit for premine period. + unsigned int nProofOfWorkLimit = UintToArith256(params.PowLimit(true)).GetCompact(); return nProofOfWorkLimit; } - else if (nHeight < params.BTGHeight + params.BTGPremineWindow + params.nPowAveragingWindow){ + else if (nHeight < params.BTGHeight + params.BTGPremineWindow + params.nDigishieldAveragingWindow) { + // Pow limit start for warm-up period. return UintToArith256(params.powLimitStart).GetCompact(); } - + else if (nHeight < params.BTGZawyLWMAHeight) { + // Regular Digishield v3. + return DigishieldGetNextWorkRequired(pindexLast, pblock, params); + } else if (nHeight < params.BTGEquihashForkHeight) { + // Zawy's LWMA (testnet launch). + return LwmaGetNextWorkRequired(pindexLast, pblock, params); + } else if (nHeight < params.BTGEquihashForkHeight + params.nZawyLwmaAveragingWindow) { + // Reduce the difficulty of the first forked block by 100x and keep it for N blocks. + if (nHeight == params.BTGEquihashForkHeight) { + return ReduceDifficultyBy(pindexLast, 100, params); + } else { + return pindexLast->nBits; + } + } else { + // Zawy's LWMA. + return LwmaGetNextWorkRequired(pindexLast, pblock, params); + } +} + +unsigned int LwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) +{ + // Special difficulty rule for testnet: + // If the new block's timestamp is more than 2 * 10 minutes + // then allow mining of a min-difficulty block. + if (params.fPowAllowMinDifficultyBlocks && + pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing * 2) { + return UintToArith256(params.PowLimit(true)).GetCompact(); + } + return LwmaCalculateNextWorkRequired(pindexLast, params); +} + +unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params) +{ + if (params.fPowNoRetargeting) { + return pindexLast->nBits; + } + + const int height = pindexLast->nHeight + 1; + const int64_t T = params.nPowTargetSpacing; + const int N = params.nZawyLwmaAveragingWindow; + const int k = params.ZawyLwmaAdjustedWeight(height); + const int dnorm = params.ZawyLwmaMinDenominator(height); + const bool limit_st = params.bZawyLwmaSolvetimeLimitation; + assert(height > N); + + arith_uint256 sum_target; + int t = 0, j = 0; + + // Loop through N most recent blocks. + for (int i = height - N; i < height; i++) { + const CBlockIndex* block = pindexLast->GetAncestor(i); + const CBlockIndex* block_Prev = block->GetAncestor(i - 1); + int64_t solvetime = block->GetBlockTime() - block_Prev->GetBlockTime(); + + if (limit_st && solvetime > 6 * T) { + solvetime = 6 * T; + } + + j++; + t += solvetime * j; // Weighted solvetime sum. + + // Target sum divided by a factor, (k N^2). + // The factor is a part of the final equation. However we divide sum_target here to avoid + // potential overflow. + arith_uint256 target; + target.SetCompact(block->nBits); + sum_target += target / (k * N * N); + } + // Keep t reasonable in case strange solvetimes occurred. + if (t < N * k / dnorm) { + t = N * k / dnorm; + } + + const arith_uint256 pow_limit = UintToArith256(params.PowLimit(true)); + arith_uint256 next_target = t * sum_target; + if (next_target > pow_limit) { + next_target = pow_limit; + } + + return next_target.GetCompact(); +} + +unsigned int DigishieldGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, + const Consensus::Params& params) +{ + assert(pindexLast != nullptr); + unsigned int nProofOfWorkLimit = UintToArith256(params.PowLimit(true)).GetCompact(); // Always postfork. + const CBlockIndex* pindexFirst = pindexLast; arith_uint256 bnTot {0}; - for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) { + for (int i = 0; pindexFirst && i < params.nDigishieldAveragingWindow; i++) { arith_uint256 bnTmp; bnTmp.SetCompact(pindexFirst->nBits); bnTot += bnTmp; @@ -43,27 +140,29 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead if (pindexFirst == NULL) return nProofOfWorkLimit; - arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow}; - - - return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params); + arith_uint256 bnAvg {bnTot / params.nDigishieldAveragingWindow}; + return DigishieldCalculateNextWorkRequired(bnAvg, pindexLast, pindexFirst, params); } -unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, int64_t nLastBlockTime, int64_t nFirstBlockTime, const Consensus::Params& params) +unsigned int DigishieldCalculateNextWorkRequired(arith_uint256 bnAvg, const CBlockIndex* pindexLast, const CBlockIndex* pindexFirst, const Consensus::Params& params) { + if (params.fPowNoRetargeting) + return pindexLast->nBits; + int64_t nLastBlockTime = pindexLast->GetMedianTimePast(); + int64_t nFirstBlockTime = pindexFirst->GetMedianTimePast(); // Limit adjustment int64_t nActualTimespan = nLastBlockTime - nFirstBlockTime; - if (nActualTimespan < params.MinActualTimespan()) - nActualTimespan = params.MinActualTimespan(); - if (nActualTimespan > params.MaxActualTimespan()) - nActualTimespan = params.MaxActualTimespan(); + if (nActualTimespan < params.DigishieldMinActualTimespan()) + nActualTimespan = params.DigishieldMinActualTimespan(); + if (nActualTimespan > params.DigishieldMaxActualTimespan()) + nActualTimespan = params.DigishieldMaxActualTimespan(); // Retarget const arith_uint256 bnPowLimit = UintToArith256(params.PowLimit(true)); arith_uint256 bnNew {bnAvg}; - bnNew /= params.AveragingWindowTimespan(); + bnNew /= params.DigishieldAveragingWindowTimespan(); bnNew *= nActualTimespan; if (bnNew > bnPowLimit) @@ -72,8 +171,6 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, int64_t nLastBlockTi return bnNew.GetCompact(); } - -// Deprecated for Bitcoin Gold unsigned int BitcoinGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { assert(pindexLast != nullptr); @@ -110,8 +207,17 @@ unsigned int BitcoinGetNextWorkRequired(const CBlockIndex* pindexLast, const CBl return BitcoinCalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); } +unsigned int ReduceDifficultyBy(const CBlockIndex* pindexLast, int64_t multiplier, const Consensus::Params& params) { + arith_uint256 target; + target.SetCompact(pindexLast->nBits); + target *= multiplier; + const arith_uint256 pow_limit = UintToArith256(params.PowLimit(true)); + if (target > pow_limit) { + target = pow_limit; + } + return target.GetCompact(); +} -// Depricated for Bitcoin Gold unsigned int BitcoinCalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { if (params.fPowNoRetargeting) @@ -139,12 +245,13 @@ 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(); + int height = pblock->nHeight; + unsigned int n = params.EquihashN(height); + unsigned int k = params.EquihashK(height); // Hash state crypto_generichash_blake2b_state state; - EhInitialiseState(n, k, state); + EhInitialiseState(n, k, state, params.EquihashUseBTGSalt(height)); // I = the block header minus nonce and solution. CEquihashInput I{*pblock}; diff --git a/src/pow.h b/src/pow.h index 292a9d6c10..c4813efa75 100644 --- a/src/pow.h +++ b/src/pow.h @@ -16,12 +16,24 @@ class CBlockIndex; class CChainParams; class uint256; +/** PoW algorithm entry. */ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); -unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, int64_t nLastBlockTime, int64_t nFirstBlockTime, const Consensus::Params& params); +/** Zawy's LWMA - next generation algorithm for testnet currently */ +unsigned int LwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); +unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params); + +/** Digishield v3 - used in Bitcoin Gold mainnet currently */ +unsigned int DigishieldGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); +unsigned int DigishieldCalculateNextWorkRequired(arith_uint256 bnAvg, const CBlockIndex* pindexLast, const CBlockIndex* pindexFirst, const Consensus::Params& params); + +/** Original Bitcoin difficulty adjustment algorithm */ unsigned int BitcoinGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params); unsigned int BitcoinCalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params); +/** Reduce the difficulty by a given multiplier. It doesn't check uint256 overflow! */ +unsigned int ReduceDifficultyBy(const CBlockIndex* pindexLast, int64_t multiplier, const Consensus::Params& params); + /** Check whether the Equihash solution in a block header is valid */ bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams&); diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index 3ee656d470..c736f0c439 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -48,5 +48,5 @@ void OpenURIDialog::on_selectFileButton_clicked() if(filename.isEmpty()) return; QUrl fileUri = QUrl::fromLocalFile(filename); - ui->uriEdit->setText("bitcoin:?r=" + QUrl::toPercentEncoding(fileUri.toString())); + ui->uriEdit->setText("bitcoingold:?r=" + QUrl::toPercentEncoding(fileUri.toString())); } diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index dce0240b4f..61c37f76ac 100644 --- a/src/rpc/mining.cpp +++ b/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. @@ -110,11 +113,14 @@ UniValue getnetworkhashps(const JSONRPCRequest& request) UniValue generateBlocks(std::shared_ptr coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript) { - static const int nInnerLoopCount = 0x10000; + static const int nInnerLoopBitcoinMask = 0x1FFFF; + static const int nInnerLoopBitcoinCount = 0x10000; static const int nInnerLoopEquihashMask = 0xFFFF; static const int nInnerLoopEquihashCount = 0xFFFF; int nHeightEnd = 0; int nHeight = 0; + int nInnerLoopCount; + int nInnerLoopMask; { // Don't keep cs_main locked LOCK(cs_main); @@ -124,8 +130,8 @@ UniValue generateBlocks(std::shared_ptr 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 pblocktemplate(BlockAssembler(Params()).CreateNewBlock(coinbaseScript->reserveScript)); @@ -138,6 +144,8 @@ UniValue generateBlocks(std::shared_ptr coinbaseScript, int nGen } if (pblock->nHeight < (uint32_t)params.GetConsensus().BTGHeight) { // Solve sha256d. + nInnerLoopMask = nInnerLoopBitcoinMask; + nInnerLoopCount = nInnerLoopBitcoinCount; while (nMaxTries > 0 && (int)pblock->nNonce.GetUint64(0) < nInnerLoopCount && !CheckProofOfWork(pblock->GetHash(), pblock->nBits, false, Params().GetConsensus())) { pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); @@ -145,8 +153,12 @@ UniValue generateBlocks(std::shared_ptr coinbaseScript, int nGen } } else { // 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); + EhInitialiseState(n, k, eh_state, params.EquihashUseBTGSalt(pblock->nHeight)); // I = the block header minus nonce and solution. CEquihashInput I{*pblock}; @@ -157,7 +169,7 @@ UniValue generateBlocks(std::shared_ptr coinbaseScript, int nGen crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size()); while (nMaxTries > 0 && - ((int)pblock->nNonce.GetUint64(0) & nInnerLoopEquihashMask) < nInnerLoopEquihashCount) { + ((int)pblock->nNonce.GetUint64(0) & nInnerLoopEquihashMask) < nInnerLoopCount) { // Yes, there is a chance every nonce could fail to satisfy the -regtest // target -- 1 in 2^(2^256). That ain't gonna happen pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); @@ -188,7 +200,7 @@ UniValue generateBlocks(std::shared_ptr coinbaseScript, int nGen if (nMaxTries == 0) { break; } - if ((int)pblock->nNonce.GetUint64(0) == nInnerLoopCount) { + if (((int)pblock->nNonce.GetUint64(0) & nInnerLoopMask) == nInnerLoopCount) { continue; } std::shared_ptr shared_pblock = std::make_shared(*pblock); @@ -414,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" @@ -585,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); @@ -727,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()))); diff --git a/src/test/equihash_tests.cpp b/src/test/equihash_tests.cpp index b487d8732b..40d7dce9cb 100644 --- a/src/test/equihash_tests.cpp +++ b/src/test/equihash_tests.cpp @@ -12,6 +12,7 @@ #include "crypto/equihash.h" #include "test/test_bitcoin.h" #include "uint256.h" +#include "utilstrencodings.h" #include "sodium.h" @@ -47,7 +48,7 @@ void PrintSolutions(std::stringstream &strm, std::set> sol void TestEquihashSolvers(unsigned int n, unsigned int k, const std::string &I, const arith_uint256 &nonce, const std::set> &solns) { size_t cBitLen { n/(k+1) }; crypto_generichash_blake2b_state state; - EhInitialiseState(n, k, state); + EhInitialiseState(n, k, state, false); 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()); @@ -86,7 +87,7 @@ 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 soln, bool expected) { size_t cBitLen { n/(k+1) }; crypto_generichash_blake2b_state state; - EhInitialiseState(n, k, state); + EhInitialiseState(n, k, state, false); uint256 V = ArithToUint256(nonce); crypto_generichash_blake2b_update(&state, (unsigned char*)&I[0], I.size()); crypto_generichash_blake2b_update(&state, V.begin(), V.size()); @@ -195,4 +196,17 @@ BOOST_AUTO_TEST_CASE(validator_testvectors) { false); } +BOOST_AUTO_TEST_CASE(validator_144_5_btg_salt) { + unsigned int n = 144; + unsigned int k = 5; + std::vector IV = ParseHex("0400000008e9694cc2120ec1b5733cc12687b609058eec4f7046a521ad1d1e3049b400003e7420ed6f40659de0305ef9b7ec037f4380ed9848bc1c015691c90aa16ff3930000000000000000000000000000000000000000000000000000000000000000c9310d5874e0001f000000000000000000000000000000010b000000000000000000000000666666"); + std::vector soln = ParseHex("01629b3779fd498defb2b0a551f7e111a8a003711acfe129622eb80bc98df66b9d8178b9670bacdc972b250fcb6715f437eb0addf858f9419c03f93a1be742e6377d4dcc4b9196afd811592ee4589cecfa321e7a9d5675338e7834923fe12b49f743a8d4"); + crypto_generichash_blake2b_state state; + EhInitialiseState(n, k, state, true); + crypto_generichash_blake2b_update(&state, (unsigned char*)&IV[0], IV.size()); + bool is_valid; + EhIsValidSolution(n, k, state, soln, is_valid); + BOOST_CHECK(is_valid); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 6e6049c21c..6245d1f25d 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -82,4 +82,35 @@ BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) BOOST_CHECK_EQUAL(tdiff, p1->GetBlockTime() - p2->GetBlockTime()); } } + +BOOST_AUTO_TEST_CASE(LwmaCalculateNextWorkRequired_test) +{ + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); + std::vector blocks(50); + for (int i = 0; i < 50; i++) { + blocks[i].pprev = i ? &blocks[i - 1] : nullptr; + blocks[i].nHeight = i; + blocks[i].nTime = 1269211443 + i * chainParams->GetConsensus().nPowTargetSpacing; + blocks[i].nBits = 0x1d00ffff; + blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0); + } + + int bits = LwmaCalculateNextWorkRequired(&blocks.back(), chainParams->GetConsensus()); + BOOST_CHECK_EQUAL(bits, 0x1d010084); +} + +BOOST_AUTO_TEST_CASE(ReduceDifficultyBy_test) +{ + const auto chain_params = CreateChainParams(CBaseChainParams::MAIN); + const auto& consensus = chain_params->GetConsensus(); + CBlockIndex last_block; + last_block.nHeight = consensus.BTGEquihashForkHeight - 1; + + // Reach the PoW limit + last_block.nBits = 0x1f00ffff; + BOOST_CHECK_EQUAL(ReduceDifficultyBy(&last_block, 256, consensus), 0x1f07ffff); + // Target raise by 256x + last_block.nBits = 0x1a00ffff; + BOOST_CHECK_EQUAL(ReduceDifficultyBy(&last_block, 256, consensus), 0x1b00ffff); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/txmempool.h b/src/txmempool.h index 6723ea8e6c..64f11d85bf 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -207,7 +207,7 @@ struct mempoolentry_txid class CompareTxMemPoolEntryByDescendantScore { public: - bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const { bool fUseADescendants = UseDescendantScore(a); bool fUseBDescendants = UseDescendantScore(b); @@ -229,7 +229,7 @@ class CompareTxMemPoolEntryByDescendantScore } // Calculate which score to use for an entry (avoiding division). - bool UseDescendantScore(const CTxMemPoolEntry &a) + bool UseDescendantScore(const CTxMemPoolEntry &a) const { double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants(); double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize(); @@ -244,7 +244,7 @@ class CompareTxMemPoolEntryByDescendantScore class CompareTxMemPoolEntryByScore { public: - bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const { double f1 = (double)a.GetModifiedFee() * b.GetTxSize(); double f2 = (double)b.GetModifiedFee() * a.GetTxSize(); @@ -258,7 +258,7 @@ class CompareTxMemPoolEntryByScore class CompareTxMemPoolEntryByEntryTime { public: - bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const { return a.GetTime() < b.GetTime(); } @@ -267,7 +267,7 @@ class CompareTxMemPoolEntryByEntryTime class CompareTxMemPoolEntryByAncestorFee { public: - bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const { double aFees = a.GetModFeesWithAncestors(); double aSize = a.GetSizeWithAncestors(); diff --git a/src/validation.cpp b/src/validation.cpp index 0a07973a42..1ffdec9806 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -42,6 +42,7 @@ #include "versionbits.h" #include "warnings.h" +#include #include #include @@ -2795,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 size_t 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 @@ -2969,7 +2980,8 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early"); // Check timestamp - if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME) + if (block.GetBlockTime() > nAdjustedTime + std::min(consensusParams.BTGMaxFutureBlockTime, + BITCOIN_MAX_FUTURE_BLOCK_TIME)) return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded: diff --git a/test/functional/btg-hardfork.py b/test/functional/btg-hardfork.py index bb73b1eab8..ae2f7e32a6 100755 --- a/test/functional/btg-hardfork.py +++ b/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 """ @@ -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__': diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py index 4f308a1a2a..5f8494f495 100755 --- a/test/functional/test_framework/mininode.py +++ b/test/functional/test_framework/mininode.py @@ -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")