From 2910478b5ae692d3828e6c915ad82ac3b7e84a1e Mon Sep 17 00:00:00 2001 From: miketout Date: Sun, 29 Apr 2018 23:21:35 -0700 Subject: [PATCH] Added LWMA difficulty algorithm for Verus, enabled compiler optimizations for verushash --- src/Makefile.am | 4 ++-- src/chainparams.cpp | 18 ++++++++++++-- src/consensus/params.h | 6 +++++ src/komodo_globals.h | 2 +- src/main.cpp | 11 +++++++-- src/miner.cpp | 6 ++--- src/pow.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 90 insertions(+), 11 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index a7cef7cd4..614952fff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -361,8 +361,8 @@ crypto_libbitcoin_crypto_a_SOURCES += \ endif # Verus hash specific library -crypto_libverus_crypto_a_CPPFLAGS = -O0 -Wint-conversion -march=native -funroll-loops -fomit-frame-pointer -fPIC $(AM_CPPFLAGS) -crypto_libverus_crypto_a_CXXFLAGS = -O0 -Wint-conversion -march=native -funroll-loops -fomit-frame-pointer -fPIC $(AM_CXXFLAGS) +crypto_libverus_crypto_a_CPPFLAGS = -O3 -Wint-conversion -march=native -funroll-loops -fomit-frame-pointer -fPIC $(AM_CPPFLAGS) +crypto_libverus_crypto_a_CXXFLAGS = -O3 -Wint-conversion -march=native -funroll-loops -fomit-frame-pointer -fPIC $(AM_CXXFLAGS) crypto_libverus_crypto_a_SOURCES = \ crypto/haraka.h \ crypto/haraka.c diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 49c4a2244..112c0947b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -83,6 +83,8 @@ extern uint16_t ASSETCHAINS_PORT; extern uint32_t ASSETCHAIN_INIT; extern uint32_t ASSETCHAINS_MAGIC; extern uint64_t ASSETCHAINS_SUPPLY; +extern uint64_t ASSETCHAINS_ALGO; +extern uint64_t ASSETCHAINS_EQUIHASH; const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); @@ -100,6 +102,8 @@ public: consensus.nMajorityWindow = 4000; consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); consensus.nPowAveragingWindow = 17; + consensus.nMaxFutureBlockTime = 7 * 60; // 7 mins + assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); consensus.nPowMaxAdjustDown = 32; // 32% adjustment down consensus.nPowMaxAdjustUp = 16; // 16% adjustment up @@ -178,7 +182,7 @@ public: vFixedSeeds = std::vector(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); - fMiningRequiresPeers = true; + //fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = true; fMineBlocksOnDemand = false; @@ -227,7 +231,15 @@ void *chainparams_commandline(void *ptr) mainParams.pchMessageStart[3] = (ASSETCHAINS_MAGIC >> 24) & 0xff; fprintf(stderr,">>>>>>>>>> %s: port.%u/%u magic.%08x %u %u coins\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_PORT,ASSETCHAINS_PORT+1,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY); - checkpointData = //(Checkpoints::CCheckpointData) + if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH) + { + // this is only good for 60 second blocks with an averaging window of 45. for other parameters, use: + // nLwmaAjustedWeight = (N+1)/2 * (0.9989^(500/nPowAveragingWindow)) * nPowTargetSpacing + mainParams.consensus.nLwmaAjustedWeight = 1350; + mainParams.consensus.nPowAveragingWindow = 45; + } + + checkpointData = //(Checkpoints::CCheckpointData) { boost::assign::map_list_of (0, mainParams.consensus.hashGenesisBlock), @@ -417,6 +429,7 @@ public: consensus.powLimit = uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.nPowAveragingWindow = 17; assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); + consensus.nMaxFutureBlockTime = 7 * 60; vAlertPubKey = ParseHex("00"); nDefaultPort = 17770; @@ -505,6 +518,7 @@ public: consensus.nMajorityWindow = 1000; consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); consensus.nPowAveragingWindow = 17; + consensus.nMaxFutureBlockTime = 7 * 60; // 7 mins assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); consensus.nPowMaxAdjustDown = 0; // Turn off adjustment down consensus.nPowMaxAdjustUp = 0; // Turn off adjustment up diff --git a/src/consensus/params.h b/src/consensus/params.h index 855729ff0..a072f50cb 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -89,12 +89,18 @@ struct Params { int nMajorityWindow; int fPowAllowMinDifficultyBlocks; NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES]; + /** Proof of work parameters */ uint256 powLimit; int64_t nPowAveragingWindow; int64_t nPowMaxAdjustDown; int64_t nPowMaxAdjustUp; int64_t nPowTargetSpacing; + int64_t nMaxFutureBlockTime; + + // Verus algorithm's lwma difficulty + int64_t nLwmaAjustedWeight; + 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; } diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 659519ed2..9179594ac 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -77,7 +77,7 @@ uint32_t ASSETCHAINS_VERUSHASH = 1; const char *ASSETCHAINS_ALGORITHMS[] = {"equihash", "verushash"}; uint64_t ASSETCHAINS_NONCEMASK[] = {0xffff,0xffffff}; uint32_t ASSETCHAINS_NONCESHIFT[] = {32,40}; -uint32_t ASSETCHAINS_HASHESPERROUND[] = {1,128}; +uint32_t ASSETCHAINS_HASHESPERROUND[] = {1,512}; uint32_t ASSETCHAINS_ALGO = _ASSETCHAINS_EQUIHASH; uint32_t KOMODO_INITDONE; diff --git a/src/main.cpp b/src/main.cpp index f9b4b97ae..926a42ffd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3598,14 +3598,21 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta { cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) << endl; return state.DoS(100, error("%s: incorrect proof of work", __func__), - REJECT_INVALID, "bad-diffbits"); + REJECT_INVALID, "bad-diffbits"); } // Check timestamp against prev if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) { return state.Invalid(error("%s: block's timestamp is too early", __func__), - REJECT_INVALID, "time-too-old"); + REJECT_INVALID, "time-too-old"); + } + + // Check that timestamp is not too far in the future + if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime) + { + return state.Invalid(error("%s: block timestamp too far in the future", __func__), + REJECT_INVALID, "time-too-new"); } if (fCheckpointsEnabled) diff --git a/src/miner.cpp b/src/miner.cpp index 586fc4977..1839f6102 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -660,13 +660,13 @@ void static BitcoinMiner_noeq() LogPrintf("KomodoMiner started\n"); SetThreadPriority(THREAD_PRIORITY_LOWEST); RenameThread("komodo-miner"); - const CChainParams& chainparams = Params(); #ifdef ENABLE_WALLET // Each thread has its own key CReserveKey reservekey(pwallet); #endif + const CChainParams& chainparams = Params(); // Each thread has its own counter unsigned int nExtraNonce = 0; std::vector solnPlaceholder = std::vector(); @@ -680,7 +680,6 @@ void static BitcoinMiner_noeq() if ( komodo_baseid(ASSETCHAINS_SYMBOL) < 0 ) break; } - miningTimer.start(); try { @@ -700,7 +699,6 @@ void static BitcoinMiner_noeq() break; MilliSleep(1000); } while (true); - miningTimer.start(); } @@ -783,7 +781,7 @@ void static BitcoinMiner_noeq() LogPrintf("KomodoMiner using %s algorithm:\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]); LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex()); - printf("FOUND BLOCK! \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex().c_str(), hashTarget.GetHex().c_str()); + printf("FOUND BLOCK %d! \n hash: %s \ntarget: %s\n", Mining_height, pblock->GetHash().GetHex().c_str(), hashTarget.GetHex().c_str()); #ifdef ENABLE_WALLET ProcessBlockFound(pblock, *pwallet, reservekey); #else diff --git a/src/pow.cpp b/src/pow.cpp index 25dab1193..55ff29954 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -22,9 +22,14 @@ uint32_t komodo_chainactive_timestamp(); extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH; +unsigned int lwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params); +unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params); unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { + if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH) + return lwmaGetNextWorkRequired(pindexLast, pblock, params); + unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); // Genesis block if (pindexLast == NULL ) @@ -83,6 +88,55 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, return bnNew.GetCompact(); } +unsigned int lwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) +{ + return lwmaCalculateNextWorkRequired(pindexLast, params); +} + +unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params) +{ + unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); + + // Find the first block in the averaging interval as we total the linearly weighted average + const CBlockIndex* pindexFirst = pindexLast; + const CBlockIndex* pindexNext; + arith_uint256 nextTarget {0}, sumTarget {0}, bnTmp; + int64_t t = 0, solvetime, k = params.nLwmaAjustedWeight, N = params.nPowAveragingWindow; + + for (int i = 0, j = N - 1; pindexFirst && i < N; i++, j--) { + pindexNext = pindexFirst; + pindexFirst = pindexFirst->pprev; + if (!pindexFirst) + break; + + solvetime = pindexNext->GetBlockTime() - pindexFirst->GetBlockTime(); + + // weighted sum + t += solvetime * j; + + // Target sum divided by a factor, (k N^2). + // The factor is a part of the final equation. However we divide + // here to avoid potential overflow. + bnTmp.SetCompact(pindexNext->nBits); + sumTarget += bnTmp / (k * N * N); + } + + // Check we have enough blocks + if (!pindexFirst) + return nProofOfWorkLimit; + + // Keep t reasonable in case strange solvetimes occurred. + if (t < N * k / 3) + t = N * k / 3; + + bnTmp = UintToArith256(params.powLimit); + nextTarget = t * sumTarget; + if (nextTarget > bnTmp) + nextTarget = bnTmp; + + return nextTarget.GetCompact(); +} + bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& params) { if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH)