From 400a0758c1cd785bcedc5864794084045849cf58 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 16 Jan 2019 20:27:35 +0800 Subject: [PATCH] Many bug fixes. VerusHash now works with PoS64 without special exemptions. Difficulty on new chains still behaves weridly, hoping resolves as chain ages. Also reduced CPU load on all staking. These changes should work better if you are not the only node staking. --- src/komodo_bitcoind.h | 29 ++++++++++++++++------------- src/komodo_globals.h | 4 +++- src/komodo_utils.h | 5 +++-- src/miner.cpp | 41 ++++++++++++++++++++++++++--------------- 4 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index bb85ef1d1..662d0703c 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1274,7 +1274,7 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh if ( value < SATOSHIDEN ) return(0); value /= SATOSHIDEN; - mindiff.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); + mindiff.SetCompact(STAKING_MIN_DIFF,&fNegative,&fOverflow); ratio = (mindiff / bnTarget); if ( (minage= nHeight*3) > 6000 ) // about 100 blocks minage = 6000; @@ -1342,11 +1342,12 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he int32_t oldflag = 0,dispflag = 0; CBlockIndex *pindex; arith_uint256 easydiff,bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,m,ht,percPoS,diff,val; *percPoSp = percPoS = 0; - if ( height <= 10 || (ASSETCHAINS_STAKED == 100 && height <= 100) ) + if ( height <= 10 || (ASSETCHAINS_STAKED == 100 && height <= 100) ) return(target); + sum = arith_uint256(0); ave = sum; - easydiff.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); + easydiff.SetCompact(STAKING_MIN_DIFF,&fNegative,&fOverflow); for (i=n=m=0; i<100; i++) { ht = height - 100 + i; @@ -1372,8 +1373,10 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 && (i % 10) == 9 ) fprintf(stderr," %d, ",percPoS); } + // We now do actual PoS % at the start. Requires coin distribution in first 10 blocks! + // This is not hard to do and stops the chain having its PoS/PoW in large chunks. if ( m+n < 100 ) - percPoS = ((percPoS * n) + (goalperc * (100-n))) / 100; + percPoS = (percPoS*100) / (m+n); if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 ) fprintf(stderr," -> %d%% percPoS vs goalperc.%d ht.%d\n",percPoS,goalperc,height); *percPoSp = percPoS; @@ -1432,7 +1435,8 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS); } } - else bnTarget = ave; // recent ave is perfect + else + bnTarget = ave; // recent ave is perfect return(bnTarget); } @@ -1468,7 +1472,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_ { if ( 0 && ASSETCHAINS_STAKED < 100 ) fprintf(stderr,"komodo_is_PoSblock PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)pblock->nTime,(int32_t)(eligible - pblock->nTime)); - if ( slowflag != 0 && pindex != 0 && height > 100) + if ( slowflag != 0 && pindex != 0 ) { pindex->segid = -1; //fprintf(stderr,"PoW block detected set segid.%d <- %d\n",height,pindex->segid); @@ -1477,7 +1481,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_ else { isPoS = 2; // 2 means staking utxo validated - if ( slowflag != 0 && height > 100 ) + if ( slowflag != 0 ) { CTxDestination voutaddress; char voutaddr[64]; if ( ExtractDestination(pblock->vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) ) @@ -1831,12 +1835,11 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) return(-1); } else { - // I think this means the block is valid PoW. We need to set the pindex->segid here. failed = 0; CBlockIndex *pindex; BlockMap::const_iterator it = mapBlockIndex.find(pblock->GetHash()); pindex = it != mapBlockIndex.end() ? it->second : NULL; - if ( pindex != 0 && height > 100 && pindex->segid == -2 ) { + if ( pindex != 0 && pindex->segid == -2 ) { pindex->segid = -1; //fprintf(stderr,"PoW block detected set segid.%d <- %d\n",height,pindex->segid); } @@ -2083,7 +2086,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt return 0; bnTarget.SetCompact(nBits, &fNegative, &fOverflow); - mindiff.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); + mindiff.SetCompact(STAKING_MIN_DIFF,&fNegative,&fOverflow); ratio = (mindiff / bnTarget); assert(pwalletMain != NULL); *utxovaluep = 0; @@ -2096,7 +2099,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt if ( (minage= nHeight*3) > 6000 ) // about 100 blocks minage = 6000; komodo_segids(hashbuf,nHeight-101,100); - if ( *blocktimep < tipindex->nTime+60 ) + if ( *blocktimep < tipindex->nTime+60) *blocktimep = tipindex->nTime+60; //fprintf(stderr,"Start scan of utxo for staking %u ht.%d\n",(uint32_t)time(NULL),nHeight); @@ -2155,7 +2158,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt //fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); } //fprintf(stderr,"numkp.%d blocktime.%u\n",numkp,*blocktimep); - block_from_future_rejecttime = (uint32_t)GetAdjustedTime() + 57; + block_from_future_rejecttime = (uint32_t)GetAdjustedTime() + 57; for (i=winners=0; inTime+27,minage,hashbuf)) == 0 ) continue; eligible = komodo_stake(0,bnTarget,nHeight,kp->txid,kp->vout,0,(uint32_t)tipindex->nTime+27,kp->address); -//fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible); + //fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible); if ( eligible > 0 ) { besttime = m = 0; diff --git a/src/komodo_globals.h b/src/komodo_globals.h index ef7af0ba2..f2f6ed6b4 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -53,7 +53,7 @@ bool VERUS_MINTBLOCKS; char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096],NOTARYADDRS[64][36]; uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_BEAMPORT,ASSETCHAINS_CODAPORT; -uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT,KOMODO_DPOWCONFS = 1; +uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT,KOMODO_DPOWCONFS = 1,STAKING_MIN_DIFF; uint32_t ASSETCHAINS_MAGIC = 2387029918; int64_t ASSETCHAINS_GENESISTXVAL = 5000000000; @@ -80,6 +80,8 @@ uint64_t ASSETCHAINS_NONCEMASK[] = {0xffff,0xfffffff}; uint32_t ASSETCHAINS_NONCESHIFT[] = {32,16}; uint32_t ASSETCHAINS_HASHESPERROUND[] = {1,4096}; uint32_t ASSETCHAINS_ALGO = _ASSETCHAINS_EQUIHASH; +// min diff returned from GetNextWorkRequired needs to be added here for each algo, so they can work with ac_staked. +uint32_t ASSETCHAINS_MINDIFF[] = {537857807,504303375}; // Verus proof of stake controls int32_t ASSETCHAINS_LWMAPOS = 0; // percentage of blocks should be PoS diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 0ac40a48b..74e82f1e2 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1684,13 +1684,13 @@ void komodo_args(char *argv0) IS_KOMODO_NOTARY = 1; KOMODO_MININGTHREADS = 1; mapArgs ["-genproclimit"] = itostr(KOMODO_MININGTHREADS); - IS_STAKED_NOTARY = -1; + IS_STAKED_NOTARY = -1; fprintf(stderr,"running as notary.%d %s\n",i,Notaries_elected1[i][0]); break; } } } - name = GetArg("-ac_name",""); + name = GetArg("-ac_name",""); if ( argv0 != 0 ) { len = (int32_t)strlen(argv0); @@ -1726,6 +1726,7 @@ void komodo_args(char *argv0) if (std::string(ASSETCHAINS_ALGORITHMS[i]) == selectedAlgo) { ASSETCHAINS_ALGO = i; + STAKING_MIN_DIFF = ASSETCHAINS_MINDIFF[i]; // only worth mentioning if it's not equihash if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH) printf("ASSETCHAINS_ALGO, algorithm set to %s\n", selectedAlgo.c_str()); diff --git a/src/miner.cpp b/src/miner.cpp index e06a570c7..e90b22a5a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -531,6 +531,19 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 //if ( blocktime > pindexPrev->GetMedianTimePast()+60 ) // blocktime = pindexPrev->GetMedianTimePast() + 60; siglen = komodo_staked(txStaked, pblock->nBits, &blocktime, &txtime, &utxotxid, &utxovout, &utxovalue, utxosig); + // if you skip this check it will create a block too far into the future and not pass ProcessBlock or AcceptBlock. + // This has been moved from the mining loop to save CPU, and to also make ac_staked work with the verus miner. + while ( blocktime-57 > GetAdjustedTime() ) + { + sleep(1); + if ( (rand() % 100) < 1 ) + fprintf(stderr, "%u seconds until elegible, waiting.\n", blocktime-((uint32_t)GetAdjustedTime()+57)); + if ( chainActive.LastTip()->GetHeight() >= stakeHeight ) + { + fprintf(stderr, "Block Arrived, reset staking loop.\n"); + return(0); + } + } } if ( siglen > 0 ) @@ -546,7 +559,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 pblock->nTime = blocktime; //printf("staking PoS ht.%d t%u lag.%u\n",(int32_t)chainActive.LastTip()->GetHeight()+1,blocktime,(uint32_t)(GetAdjustedTime() - (blocktime-13))); } else return(0); //fprintf(stderr,"no utxos eligible for staking\n"); - + } // Create coinbase tx CMutableTransaction txNew = CreateNewContextualCMutableTransaction(consensusParams, nHeight); @@ -838,7 +851,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, scriptPubKey = Marmara_scriptPubKey(nHeight,pubkey); if ( ASSETCHAINS_STAKED != 0 && KOMODO_MININGTHREADS == 0 ) isStake = true; - return CreateNewBlock(pubkey,scriptPubKey, gpucount, isStake); + return CreateNewBlock(pubkey, scriptPubKey, gpucount, isStake); } void komodo_broadcast(CBlock *pblock,int32_t limit) @@ -1241,7 +1254,7 @@ void static BitcoinMiner_noeq() if ( ptr == 0 ) { static uint32_t counter; - if ( counter++ < 10 ) + if ( ASSETCHAINS_STAKED == 0 && counter++ < 10 ) fprintf(stderr,"created illegal block, retry\n"); continue; } @@ -1301,10 +1314,12 @@ void static BitcoinMiner_noeq() if ( ASSETCHAINS_STAKED != 0 ) { - int32_t percPoS,z; - hashTarget = komodo_PoWtarget(&percPoS,hashTarget,Mining_height,ASSETCHAINS_STAKED); + int32_t percPoS,z; bool fNegative,fOverflow; + HASHTarget_POW = komodo_PoWtarget(&percPoS,hashTarget,Mining_height,ASSETCHAINS_STAKED); + // We use equihash min diff here to make the verus miner instantly finds a blockhash, this saves CPU when staking. + HASHTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); if ( ASSETCHAINS_STAKED < 100 ) - LogPrintf("Block %d : PoS %d%% vs target %d%% \n",Mining_height,percPoS,(int32_t)ASSETCHAINS_STAKED); + LogPrintf("Block %d : PoS %d%% vs target %d%%\n", Mining_height, percPoS, (int32_t)ASSETCHAINS_STAKED); } while (true) @@ -1319,6 +1334,9 @@ void static BitcoinMiner_noeq() vh.ClearExtra(); int64_t i, count = ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO] + 1; int64_t hashesToGo = ASSETCHAINS_HASHESPERROUND[ASSETCHAINS_ALGO]; + if ( KOMODO_MININGTHREADS > 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 ) + hashTarget = HASHTarget_POW; + else hashTarget = HASHTarget; // for speed check NONCEMASK at a time for (i = 0; i < count; i++) @@ -1414,7 +1432,6 @@ void static BitcoinMiner_noeq() printf("%lu mega hashes complete - working\n", (ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO] + 1) / 1048576); #endif break; - } } } @@ -1724,12 +1741,6 @@ void static BitcoinMiner() } else { - while ( B.nTime-57 > GetAdjustedTime() ) - { - sleep(1); - if ( chainActive.LastTip()->GetHeight() >= Mining_height ) - return(false); - } uint256 tmp = B.GetHash(); int32_t z; for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&tmp)[z]); @@ -1938,12 +1949,12 @@ void static BitcoinMiner() for (int i = 0; i < nThreads; i++) { #ifdef ENABLE_WALLET - if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH || (ASSETCHAINS_STAKED != 0 && KOMODO_MININGTHREADS == 0) ) + if ( ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH ) minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet)); else minerThreads->create_thread(boost::bind(&BitcoinMiner_noeq, pwallet)); #else - if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH || (ASSETCHAINS_STAKED != 0 && KOMODO_MININGTHREADS == 0) ) + if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH ) minerThreads->create_thread(&BitcoinMiner); else minerThreads->create_thread(&BitcoinMiner_noeq);