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);