diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 06bc5ed..8a6b1ec 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -65,30 +65,32 @@ public: CMainParams() { strNetworkID = CBaseChainParams::MAIN; consensus.nSubsidyHalvingInterval = 100000; - consensus.BIP16Exception = uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22"); - consensus.BIP34Height = 30000; - consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"); - consensus.BIP65Height = 30000; // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 - consensus.BIP66Height = 30000; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 - consensus.CSVHeight = 30000; // 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5 - consensus.SegwitHeight = 30000; // 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893 - consensus.MinBIP9WarningHeight = 30000; // segwit activation height + miner confirmation window + consensus.BIP16Exception = uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); + consensus.BIP34Height = 29000; + consensus.BIP34Hash = uint256(); + consensus.BIP65Height = 29000; + consensus.BIP66Height = 29000; + consensus.CSVHeight = 29000; + consensus.SegwitHeight = 29000; + consensus.MinBIP9WarningHeight = 29240; // segwit activation height + miner confirmation window consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 0.025 * 24 * 60 * 60; // 36 Minutes - consensus.nPowTargetSpacing = 2 * 60; + consensus.powLimitV2 = uint256S("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowTargetTimespan = 0.025 * 24 * 60 * 60; + consensus.nPowTargetSpacing = 10 * 60; + consensus.nPowTargetSpacingV2 = 2 * 60; consensus.fPowAllowMinDifficultyBlocks = false; consensus.fPowNoRetargeting = false; - consensus.nRuleChangeActivationThreshold = 475; // 95% of 500 - consensus.nMinerConfirmationWindow = 500; // PowTargetTimespan / nPowTargetSpacing + consensus.nRuleChangeActivationThreshold = 180; + consensus.nMinerConfirmationWindow = 240; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000000100010001"); + consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000001578157d557d557aa0"); // By default assume that the signatures in ancestors of this block are valid. - consensus.defaultAssumeValid = uint256S("0x0000000000000000000f2adce67e49b0b6bdeb9de8b7c3d7e93b21e7fc1e819d"); // 623950 + consensus.defaultAssumeValid = uint256S("0x0000000000000014351dee34029945d5a4dea299ec8843626695c88b084b4d10"); /** * The message start string is designed to be unlikely to occur in normal data. @@ -140,18 +142,21 @@ public: checkpointData = { { {0, uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")}, + {1, uint256S("0x00000000082962e4c2838933cb63507142c1abb748d84b7ddce6bb233d6407e0")}, + {16, uint256S("0x000000004cc3eca82841f0691e6231b86c3b269e447fa7d6e7221cd42f725390")}, {69, uint256S("0x00000000ae75d0169080e9f0ddbcd80827eda623cfe1f4a2b1be6dcd49b916e6")}, - {10000, uint256S("0x0000000001608f591faaffdf8e7efe89f7ace0dbf2b5f2fa3ac8da3b4e59442f")}, - {20000, uint256S("0x00000000000018ffaa9a332cfb418b5c8c3f988cf26598e378bbea9e93d26f74")}, - {28879, uint256S("0x0000000000000017e9e74b9b403b775098905418b1333e9612f510af66746aa7")} + {22170, uint256S("0x000000000000086425f826a2eb60c588aefd3e0783ddeccf0f4f0c985d348e69")}, + {26619, uint256S("0x00000000000000d66df607146de7d9b423cf97150beb804d22439d199e868ca9")}, + {28879, uint256S("0x0000000000000017e9e74b9b403b775098905418b1333e9612f510af66746aa7")}, + {28925, uint256S("0x0000000000000014351dee34029945d5a4dea299ec8843626695c88b084b4d10")} } }; chainTxData = ChainTxData{ - // Data from RPC: getchaintxstats 10000 00000000000018ffaa9a332cfb418b5c8c3f988cf26598e378bbea9e93d26f74 - /* nTime */ 1711734350, - /* nTxCount */ 20016, - /* dTxRate */ 0.3166703578321258, + // Data from RPC: getchaintxstats + /* nTime */ 1712377887, + /* nTxCount */ 29654, + /* dTxRate */ 0.01771170546987923, }; } }; diff --git a/src/consensus/params.h b/src/consensus/params.h index 1152255..234b5c4 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -73,9 +73,11 @@ struct Params { BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]; /** Proof of work parameters */ uint256 powLimit; + uint256 powLimitV2; bool fPowAllowMinDifficultyBlocks; bool fPowNoRetargeting; int64_t nPowTargetSpacing; + int64_t nPowTargetSpacingV2; int64_t nPowTargetTimespan; int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } uint256 nMinimumChainWork; diff --git a/src/pow.cpp b/src/pow.cpp index 135b111..9c5c461 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -14,6 +14,14 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead { assert(pindexLast != nullptr); unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); + unsigned int nProofOfWorkLimitV2 = UintToArith256(params.powLimitV2).GetCompact(); + + // reset difficulty for new diff algorithm's average + Segwit/CSV activation + if (pindexLast->nHeight >= 28927) + return nProofOfWorkLimitV2; + + if (pindexLast->nHeight >= 28930) + return LwmaCalculateNextWorkRequired(pindexLast, params); // Only change once per difficulty adjustment interval if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) @@ -46,6 +54,57 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); } +unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params) +{ + const int64_t T = params.nPowTargetSpacingV2; + const int64_t N = 240; + const int64_t k = N * (N + 1) * T / 2; // For T=120, 240, 600 use approx N=100, 75, 50 + const int64_t height = pindexLast->nHeight; + const arith_uint256 powLimit = UintToArith256(params.powLimit); + + if (height < N) { return powLimit.GetCompact(); } + + arith_uint256 sumTarget, nextTarget; + int64_t thisTimestamp, previousTimestamp; + int64_t t = 0, j = 0; + + // Uncomment next 2 lines to use LWMA-3 jump rule. + //arith_uint256 previousTarget = 0; + //int64_t sumLast3Solvetimes = 0; + + const CBlockIndex* blockPreviousTimestamp = pindexLast->GetAncestor(height - N); + previousTimestamp = blockPreviousTimestamp->GetBlockTime(); + + // Loop through N most recent blocks. + for (int64_t i = height - N + 1; i <= height; i++) { + const CBlockIndex* block = pindexLast->GetAncestor(i); + thisTimestamp = (block->GetBlockTime() > previousTimestamp) ? + block->GetBlockTime() : previousTimestamp + 1; + + int64_t solvetime = std::min(6 * T, thisTimestamp - previousTimestamp); + previousTimestamp = thisTimestamp; + + j++; + t += solvetime * j; // Weighted solvetime sum. + arith_uint256 target; + target.SetCompact(block->nBits); + sumTarget += target / (k * N); + + // Uncomment next 2 lines to use LWMA-3. + // if (i > height - 3) { sumLast3Solvetimes += solvetime; } + // if (i == height) { previousTarget = target.SetCompact(block->nBits); } + } + nextTarget = t * sumTarget; + + // Uncomment the following to use LWMA-3. + // This is a "memory-less" jump in difficulty approximately 2x normal + // if (sumLast3Solvetimes < (8 * T) / 10) { nextTarget = (previousTarget*100)/(100+(N*26)/200); } + + if (nextTarget > powLimit) { nextTarget = powLimit; } + + return nextTarget.GetCompact(); +} + unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { if (params.fPowNoRetargeting) diff --git a/src/pow.h b/src/pow.h index a391be8..72015fc 100644 --- a/src/pow.h +++ b/src/pow.h @@ -16,6 +16,7 @@ class uint256; unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&); +unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params&); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);