git / moonbite-core / src/test/pow_tests.cpp · raw

// Copyright (c) 2015-2019 The Bitcoin Core developers// Distributed under the MIT software license, see the accompanying// file COPYING or http://www.opensource.org/licenses/mit-license.php.#include <chain.h>#include <chainparams.h>#include <pow.h>#include <test/util/setup_common.h>#include <boost/test/unit_test.hpp>BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup)/* Test calculation of next difficulty target with no constraints applying */BOOST_AUTO_TEST_CASE(get_next_work){    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);    // MoonBite: 60 blocks took 9000 s instead of the 7200 s target (1.25x), so    // the target loosens by 1.25x with no clamp applied.    int64_t nLastRetargetTime = 1358118740;    CBlockIndex pindexLast;    pindexLast.nHeight = 59;    pindexLast.nTime = 1358118740 + 9000;    pindexLast.nBits = 0x1c0ac141;    BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1c0d7191U);}/* Test the constraint on the upper bound for next work */BOOST_AUTO_TEST_CASE(get_next_work_pow_limit){    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);    // MoonBite: at the genesis floor (0x1f0ffff0) with slow blocks the result    // is clamped to powLimit (0x1f0fffff). This also exercises the overflow    // headroom in CalculateNextWorkRequired: target * 28800 exceeds 256 bits.    int64_t nLastRetargetTime = 1756479600;    CBlockIndex pindexLast;    pindexLast.nHeight = 59;    pindexLast.nTime = 1756479600 + 100000;    pindexLast.nBits = 0x1f0ffff0;    BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1f0fffffU);}/* Test the constraint on the lower bound for actual time taken */BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual){    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);    // MoonBite: 60 blocks in 100 s is clamped to timespan/4 -> target / 4.    int64_t nLastRetargetTime = 1401682934;    CBlockIndex pindexLast;    pindexLast.nHeight = 119;    pindexLast.nTime = 1401682934 + 100;    pindexLast.nBits = 0x1b075cf1;    BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1b01d73cU);}/* Test the constraint on the upper bound for actual time taken */BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual){    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);    // MoonBite: 60 blocks in 100000 s is clamped to timespan*4 -> target * 4.    int64_t nLastRetargetTime = 1463690315;    CBlockIndex pindexLast;    pindexLast.nHeight = 179;    pindexLast.nTime = 1463690315 + 100000;    pindexLast.nBits = 0x1b015318;    BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1b054c60U);}BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_negative_target){    const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();    uint256 hash;    unsigned int nBits;    nBits = UintToArith256(consensus.powLimit).GetCompact(true);    hash.SetHex("0x1");    BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus));}BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_overflow_target){    const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();    uint256 hash;    unsigned int nBits = ~0x00800000;    hash.SetHex("0x1");    BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus));}BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_too_easy_target){    const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();    uint256 hash;    unsigned int nBits;    arith_uint256 nBits_arith = UintToArith256(consensus.powLimit);    nBits_arith *= 2;    nBits = nBits_arith.GetCompact();    hash.SetHex("0x1");    BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus));}BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_biger_hash_than_target){    const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();    uint256 hash;    unsigned int nBits;    arith_uint256 hash_arith = UintToArith256(consensus.powLimit);    nBits = hash_arith.GetCompact();    hash_arith *= 2; // hash > nBits    hash = ArithToUint256(hash_arith);    BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus));}BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_zero_target){    const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();    uint256 hash;    unsigned int nBits;    arith_uint256 hash_arith{0};    nBits = hash_arith.GetCompact();    hash = ArithToUint256(hash_arith);    BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus));}BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test){    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);    std::vector<CBlockIndex> blocks(10000);    for (int i = 0; i < 10000; i++) {        blocks[i].pprev = i ? &blocks[i - 1] : nullptr;        blocks[i].nHeight = i;        blocks[i].nTime = 1269211443 + i * chainParams->GetConsensus().nPowTargetSpacing;        blocks[i].nBits = 0x207fffff; /* target 0x7fffff000... */        blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0);    }    for (int j = 0; j < 1000; j++) {        CBlockIndex *p1 = &blocks[InsecureRandRange(10000)];        CBlockIndex *p2 = &blocks[InsecureRandRange(10000)];        CBlockIndex *p3 = &blocks[InsecureRandRange(10000)];        int64_t tdiff = GetBlockProofEquivalentTime(*p1, *p2, *p3, chainParams->GetConsensus());        BOOST_CHECK_EQUAL(tdiff, p1->GetBlockTime() - p2->GetBlockTime());    }}void sanity_check_chainparams(const ArgsManager& args, std::string chainName){    const auto chainParams = CreateChainParams(args, chainName);    const auto consensus = chainParams->GetConsensus();    // hash genesis is correct    BOOST_CHECK_EQUAL(consensus.hashGenesisBlock, chainParams->GenesisBlock().GetHash());    // target timespan is an even multiple of spacing    BOOST_CHECK_EQUAL(consensus.nPowTargetTimespan % consensus.nPowTargetSpacing, 0);    // genesis nBits is positive, doesn't overflow and is lower than powLimit    arith_uint256 pow_compact;    bool neg, over;    pow_compact.SetCompact(chainParams->GenesisBlock().nBits, &neg, &over);    BOOST_CHECK(!neg && pow_compact != 0);    BOOST_CHECK(!over);    BOOST_CHECK(UintToArith256(consensus.powLimit) >= pow_compact);    // check max target * 4*nPowTargetTimespan doesn't overflow -- see pow.cpp:CalculateNextWorkRequired()    /* Litecoin: we allow overflowing by 1 bit    if (!consensus.fPowNoRetargeting) {        arith_uint256 targ_max("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");        targ_max /= consensus.nPowTargetTimespan*4;        BOOST_CHECK(UintToArith256(consensus.powLimit) < targ_max);    }    */}BOOST_AUTO_TEST_CASE(ChainParams_MAIN_sanity){    sanity_check_chainparams(*m_node.args, CBaseChainParams::MAIN);}BOOST_AUTO_TEST_CASE(ChainParams_REGTEST_sanity){    sanity_check_chainparams(*m_node.args, CBaseChainParams::REGTEST);}BOOST_AUTO_TEST_CASE(ChainParams_TESTNET_sanity){    sanity_check_chainparams(*m_node.args, CBaseChainParams::TESTNET);}BOOST_AUTO_TEST_CASE(ChainParams_SIGNET_sanity){    sanity_check_chainparams(*m_node.args, CBaseChainParams::SIGNET);}BOOST_AUTO_TEST_SUITE_END()