diff --git a/src/init.cpp b/src/init.cpp index 6f7f91988..fa55e8586 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1911,7 +1911,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) PruneAndFlush(); } } - if ( KOMODO_NSPV >= 0 ) + if ( KOMODO_NSPV == 0 ) { if ( GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX) != 0 ) nLocalServices |= NODE_ADDRINDEX; diff --git a/src/miner.cpp b/src/miner.cpp index 54af1d021..5b0d2658f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1920,9 +1920,9 @@ void static BitcoinMiner() if ( !TestBlockValidity(state,B, chainActive.LastTip(), true, false)) { h = UintToArith256(B.GetHash()); - for (z=31; z>=0; z--) - fprintf(stderr,"%02x",((uint8_t *)&h)[z]); - fprintf(stderr," Invalid block mined, try again\n"); + //for (z=31; z>=0; z--) + // fprintf(stderr,"%02x",((uint8_t *)&h)[z]); + //fprintf(stderr," Invalid block mined, try again\n"); gotinvalid = 1; return(false); } diff --git a/src/pow.cpp b/src/pow.cpp index a84db0015..ac27e5d34 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -42,6 +42,191 @@ uint32_t komodo_chainactive_timestamp(); unsigned int lwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params); unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params); +/* from zawy repo + Preliminary code for super-fast increases in difficulty. + Requires the ability to change the difficulty during the current block, + based on the timestamp the miner selects. See my github issue #36 and KMD. + Needs intr-block exponential decay function because + this can make difficulty jump very high. + Miners need to caclulate new difficulty with each second, or + maybe 3 seconds. FTL, MTP, and revert to local times must be small. + MTP=1 if using Digishield. Out-of-sequence timestamps must be forbidden. + 1) bnTarget = Digishield() or other baseline DA + 2) bnTarget = RT_CST_RST() + 3) bnTarget = max(bnTarget,expdecay()) + RT_CST_RST() multiplies Recent Target(s), Current Solvetimes, & + Recent SolveTime if RST had an unlikely 1/200 block chance of + being too fast on accident. This estimates and adjusts for recent + hashrate aggressively (lots of random error) but corrects the error by + CST adjusting the difficulty during the block. + It checks to see if there was an "active trigger" still in play which + occurs when recent block emission rate has been too fast. Triggers + are supposed to be active if emission rate has not slowed up enough + to get back on track. It checks the longest range first because it's + the least aggressive. + T = target blocktime + ts = timestamp vector, 62 elements, 62 is oldest (elements needed are 50+W) + ct = cumulative targets, 62 elements, 62 is oldest + W = window size of recent solvetimes and targets to use that estimates hashrate + numerator & deonominator needed for 1/200 possion estimator + past = how far back in past to look for beginning of a trigger + */ + +/* create ts and cw vectors +// Get bnTarget = Digishield(); + +arith_uint256 past = 50; + +arith_uint256 W = 12; +arith_uint256 numerator = 12; +arith_uint256 denominator = 7; + +// bnTarget = RT_CST_RST (bnTarget, ts, cw, numerator, denominator, W, T, past); + +W = 6; top = 7; denominator = 3; + +// bnTarget = RT_CST_RST (bnTarget, ts, cw, numerator, denominator, W, T, past); + +W = 3; top = 1; denominator = 2; + +bnTarget = RT_CST_RST (bnTarget, ts, cw, numerator, denominator, W, T, past); +*/ + +#define T ASSETCHAINS_BLOCKTIME +#define K ((int64_t)1000000) + +#ifdef original_algo +arith_uint256 oldRT_CST_RST(int32_t height,uint32_t nTime,arith_uint256 bnTarget,uint32_t *ts,arith_uint256 *ct,int32_t numerator,int32_t denominator,int32_t W,int32_t past) +{ + //if (ts.size() < 2*W || ct.size() < 2*W ) { exit; } // error. a vector was too small + //if (ts.size() < past+W || ct.size() < past+W ) { past = min(ct.size(), ts.size()) - W; } // past was too small, adjust + int64_t altK; int32_t i,j,k,ii=0; // K is a scaling factor for integer divisions + if ( height < 64 ) + return(bnTarget); + //if ( ((ts[0]-ts[W]) * W * 100)/(W-1) < (T * numerator * 100)/denominator ) + if ( (ts[0] - ts[W]) < (T * numerator)/denominator ) + { + //bnTarget = ((ct[0]-ct[1])/K) * max(K,(K*(nTime-ts[0])*(ts[0]-ts[W])*denominator/numerator)/T/T); + bnTarget = ct[0] / arith_uint256(K); + //altK = (K * (nTime-ts[0]) * (ts[0]-ts[W]) * denominator * W) / (numerator * (W-1) * (T * T)); + altK = (K * (nTime-ts[0]) * (ts[0]-ts[W]) * denominator) / (numerator * (T * T)); + fprintf(stderr,"ht.%d initial altK.%lld %d * %d * %d / %d\n",height,(long long)altK,(nTime-ts[0]),(ts[0]-ts[W]),denominator,numerator); + if ( altK > K ) + altK = K; + bnTarget *= arith_uint256(altK); + if ( altK < K ) + return(bnTarget); + } + /* Check past 24 blocks for any sum of 3 STs < T/2 triggers. This is messy + because the blockchain does not allow us to store a variable to know + if we are currently in a triggered state that is making a sequence of + adjustments to prevTargets, so we have to look for them. + Nested loops do this: if block emission has not slowed to be back on track at + any time since most recent trigger and we are at current block, aggressively + adust prevTarget. */ + + for (j=past-1; j>=2; j--) + { + if ( ts[j]-ts[j+W] < T*numerator/denominator ) + { + ii = 0; + for (i=j-2; i>=0; i--) + { + ii++; + // Check if emission caught up. If yes, "trigger stopped at i". + // Break loop to try more recent j's to see if trigger activates again. + if ( (ts[i] - ts[j+W]) > (ii+W)*T ) + break; + + // We're here, so there was a TS[j]-TS[j-3] < T/2 trigger in the past and emission rate has not yet slowed up to be back on track so the "trigger is still active", aggressively adjusting target here at block "i" + if ( i == 0 ) + { + /* We made it all the way to current block. Emission rate since + last trigger never slowed enough to get back on track, so adjust again. + If avg last 3 STs = T, this increases target to prevTarget as ST increases to T. + This biases it towards ST=~1.75*T to get emission back on track. + If avg last 3 STs = T/2, target increases to prevTarget at 2*T. + Rarely, last 3 STs can be 1/2 speed => target = prevTarget at T/2, & 1/2 at T.*/ + + //bnTarget = ((ct[0]-ct[W])/W/K) * (K*(nTime-ts[0])*(ts[0]-ts[W]))/W/T/T; + bnTarget = ct[0]; + for (k=1; k mintarget ) + bnTarget = mintarget; + { + int32_t z; + for (z=31; z>=0; z--) + fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[z]); + } + fprintf(stderr," ht.%d initial outerK.%lld %d * %d * %d / %d\n",height,(long long)outerK,(nTime-ts[0]),(ts[0]-ts[W]),denominator,numerator); + } //else fprintf(stderr,"ht.%d no outer trigger %d >= %d\n",height,(ts[0] - ts[W]),(T * numerator)/denominator); + return(bnTarget); +} + +arith_uint256 RT_CST_RST_target(int32_t height,uint32_t nTime,arith_uint256 bnTarget,uint32_t *ts,arith_uint256 *ct,int32_t width) +{ + int32_t i; int64_t innerK; + bnTarget = ct[0]; + for (i=1; i=0; z--) + fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[z]); + fprintf(stderr," ht.%d innerK %lld (%d * %d) %u - %u width.%d\n",height,(long long)innerK,(nTime-ts[0]),(ts[0]-ts[width]),ts[0],ts[width],width); + } + return(bnTarget); +} + +arith_uint256 RT_CST_RST_inner(int32_t height,uint32_t nTime,arith_uint256 bnTarget,uint32_t *ts,arith_uint256 *ct,int32_t W,int32_t outeri) +{ + arith_uint256 mintarget; int32_t expected,elapsed,width = outeri+W; + expected = (width+1) * T; + if ( (elapsed= (ts[0] - ts[width])) < expected ) + { + mintarget = (bnTarget / arith_uint256(11)) * arith_uint256(10); + bnTarget = RT_CST_RST_target(height,nTime,bnTarget,ts,ct,W); + if ( bnTarget > mintarget ) // force zawyflag to 1 + bnTarget = mintarget; + { + int32_t z; + for (z=31; z>=0; z--) + fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[z]); + } + fprintf(stderr," height.%d O.%-2d, W.%-2d width.%-2d %4d vs %-4d, deficit %4d tip.%d\n",height,outeri,W,width,(ts[0] - ts[width]),expected,expected - (ts[0] - ts[width]),nTime-ts[0]); + } + return(bnTarget); +} + arith_uint256 zawy_targetMA(arith_uint256 easy,arith_uint256 bnSum,int32_t num,int32_t numerator,int32_t divisor) { bnSum /= arith_uint256(ASSETCHAINS_BLOCKTIME * num * num * divisor); @@ -51,21 +236,58 @@ arith_uint256 zawy_targetMA(arith_uint256 easy,arith_uint256 bnSum,int32_t num,i return(bnSum); } -arith_uint256 zawy_exponential(arith_uint256 bnTarget,int32_t mult) +int64_t zawy_exponential_val360000(int32_t num) { int32_t i,n,modval; int64_t A = 1, B = 3600 * 100; - if ( (n= (mult/ASSETCHAINS_BLOCKTIME)) > 0 ) + if ( (n= (num/ASSETCHAINS_BLOCKTIME)) > 0 ) { for (i=1; i<=n; i++) A *= 3; } - if ( (modval= (mult % ASSETCHAINS_BLOCKTIME)) != 0 ) + if ( (modval= (num % ASSETCHAINS_BLOCKTIME)) != 0 ) { B += (3600 * 110 * modval) / ASSETCHAINS_BLOCKTIME; B += (3600 * 60 * modval * modval) / (ASSETCHAINS_BLOCKTIME * ASSETCHAINS_BLOCKTIME); } + return(A * B); +} + +arith_uint256 zawy_exponential(arith_uint256 bnTarget,int32_t mult) +{ bnTarget /= arith_uint256(100 * 3600); - bnTarget *= arith_uint256(A * B); + bnTarget *= arith_uint256(zawy_exponential_val360000(mult)); + return(bnTarget); +} + +arith_uint256 zawy_ctB(arith_uint256 bnTarget,uint32_t solvetime) +{ + int64_t num; + num = ((int64_t)1000 * solvetime * solvetime * 1000) / (T * T * 784); + if ( num > 1 ) + { + bnTarget /= arith_uint256(1000); + bnTarget *= arith_uint256(num); + } + return(bnTarget); +} + +arith_uint256 zawy_TSA_EMA(int32_t height,int32_t tipdiff,arith_uint256 prevTarget,int32_t solvetime) +{ + arith_uint256 A,B,C,bnTarget; + if ( tipdiff < 4 ) + tipdiff = 4; + tipdiff &= ~1; + bnTarget = prevTarget / arith_uint256(K*T); + A = bnTarget * arith_uint256(T); + B = (bnTarget / arith_uint256(360000)) * arith_uint256(tipdiff * zawy_exponential_val360000(tipdiff/2)); + C = (bnTarget / arith_uint256(360000)) * arith_uint256(T * zawy_exponential_val360000(tipdiff/2)); + bnTarget = ((A + B - C) / arith_uint256(tipdiff)) * arith_uint256(K*T); + { + int32_t z; + for (z=31; z>=0; z--) + fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[z]); + } + fprintf(stderr," ht.%d TSA bnTarget tipdiff.%d\n",height,tipdiff); return(bnTarget); } @@ -100,40 +322,50 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead // Find the first block in the averaging interval const CBlockIndex* pindexFirst = pindexLast; - arith_uint256 bnTmp,bnTarget,bnPrev {0},bnSum4 {0},bnSum7 {0},bnSum12 {0},bnTot {0}; - uint32_t nbits,blocktime,block4diff=0,block7diff=0,block12diff=0; int32_t diff,mult = 0; - if ( ASSETCHAINS_ADAPTIVEPOW > 0 && pindexFirst != 0 && pblock != 0 ) + arith_uint256 ct[64],ctinv[64],bnTmp,bnPrev,bnTarget,bnTarget6,bnTarget12,bnTot {0}; + uint32_t nbits,blocktime,ts[sizeof(ct)/sizeof(*ct)]; int32_t zflags[sizeof(ct)/sizeof(*ct)],i,diff,height=0,mult = 0,tipdiff = 0; + memset(ts,0,sizeof(ts)); + memset(ct,0,sizeof(ct)); + memset(ctinv,0,sizeof(ctinv)); + memset(zflags,0,sizeof(zflags)); + if ( pindexLast != 0 ) + height = (int32_t)pindexLast->GetHeight() + 1; + if ( ASSETCHAINS_ADAPTIVEPOW > 0 && pindexFirst != 0 && pblock != 0 && height >= (int32_t)(sizeof(ct)/sizeof(*ct)) ) { - mult = pblock->nTime - pindexFirst->nTime - 7 * ASSETCHAINS_BLOCKTIME; + tipdiff = (pblock->nTime - pindexFirst->nTime); + mult = tipdiff - 7 * ASSETCHAINS_BLOCKTIME; bnPrev.SetCompact(pindexFirst->nBits); - //fprintf(stderr,"ht.%d mult.%d = (%u - %u - 7x)\n",pindexLast->GetHeight(),(int32_t)mult,pblock->nTime, pindexFirst->nTime); + for (i=0; pindexFirst != 0 && i<(int32_t)(sizeof(ct)/sizeof(*ct)); i++) + { + zflags[i] = (pindexFirst->nBits & 3); + ct[i].SetCompact(pindexFirst->nBits); + ts[i] = pindexFirst->nTime; + pindexFirst = pindexFirst->pprev; + } + for (i=0; pindexFirst != 0 && i<(int32_t)(sizeof(ct)/sizeof(*ct))-1; i++) + { + if ( zflags[i] == 1 || zflags[i] == 2 ) // I, O and if TSA made it harder + ct[i] = zawy_ctB(ct[i],ts[i] - ts[i+1]); + } + if ( ASSETCHAINS_ADAPTIVEPOW == 2 ) // TSA + { + bnTarget = zawy_TSA_EMA(height,tipdiff,ct[0],ts[0] - ts[1]); + nbits = bnTarget.GetCompact(); + nbits = (nbits & 0xfffffffc) | 0; + return(nbits); + } } - for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) + pindexFirst = pindexLast; + for (i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) { bnTmp.SetCompact(pindexFirst->nBits); - bnTot += bnTmp; if ( ASSETCHAINS_ADAPTIVEPOW > 0 && pblock != 0 ) { blocktime = pindexFirst->nTime; diff = (pblock->nTime - blocktime); //fprintf(stderr,"%d ",diff); - if ( i < 12 ) + if ( i < 6 ) { - if ( i == 3 ) - { - block4diff = diff; - bnSum4 = bnTot; - } - else if ( i == 6 ) - { - block7diff = diff; - bnSum7 = bnTot; - } - else if ( i == 11 ) - { - block12diff = diff; - bnSum12 = bnTot; - } diff -= (8+i)*ASSETCHAINS_BLOCKTIME; if ( diff > mult ) { @@ -141,63 +373,93 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead mult = diff; } } + //if ( zflags[i] != 0 && zflags[0] != 0 ) + // bnTmp = (ct[i] / arith_uint256(3)); } + bnTot += bnTmp; pindexFirst = pindexFirst->pprev; } - //fprintf(stderr,"diffs %d\n",(int32_t) pindexLast->GetHeight()); + //fprintf(stderr,"diffs %d\n",height); // Check we have enough blocks if (pindexFirst == NULL) return nProofOfWorkLimit; - bool fNegative,fOverflow; int32_t flag = 0; arith_uint256 easy,origtarget,bnAvg {bnTot / params.nPowAveragingWindow}; + bool fNegative,fOverflow; int32_t past,zawyflag = 0; arith_uint256 easy,origtarget,bnAvg {bnTot / params.nPowAveragingWindow}; nbits = CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params); - if ( ASSETCHAINS_ADAPTIVEPOW > 0 && block12diff != 0 && block7diff != 0 && block4diff != 0 ) + if ( ASSETCHAINS_ADAPTIVEPOW > 0 ) { - origtarget = bnTarget = arith_uint256().SetCompact(nbits); - easy.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow); - bnSum4 = zawy_targetMA(easy,bnSum4,4,block4diff * 5,1); - bnSum7 = zawy_targetMA(easy,bnSum7,7,block7diff * 3,1); - bnSum12 = zawy_targetMA(easy,bnSum12,12,block12diff * 2,1); - if ( bnSum4 < bnSum7 ) - bnTmp = bnSum4; - else bnTmp = bnSum7; - if ( bnSum12 < bnTmp ) - bnTmp = bnSum12; - if ( bnTmp < bnTarget ) + bnTarget = arith_uint256().SetCompact(nbits); + if ( height > (int32_t)(sizeof(ct)/sizeof(*ct)) && pblock != 0 && tipdiff > 0 ) { - fprintf(stderr,"ht.%d block12diff %d vs %d, make harder\n",(int32_t)pindexLast->GetHeight()+1,block12diff,ASSETCHAINS_BLOCKTIME*11); - bnTarget = (bnTmp + bnPrev) / arith_uint256(2); - flag = 1; - } - else if ( flag == 0 && mult > 1 ) // e^mult case, jl777: test of mult > 1 failed when it was int64_t??? - { - flag = 1; - bnTarget = zawy_exponential(bnTarget,mult); - if ( bnTarget < origtarget || bnTarget > easy ) + easy.SetCompact(KOMODO_MINDIFF_NBITS & (~3),&fNegative,&fOverflow); + if ( pblock != 0 ) { - bnTarget = easy; - fprintf(stderr,"cmp.%d mult.%d ht.%d -> easy target\n",mult>1,(int32_t)mult,(int32_t)pindexLast->GetHeight()); - return(KOMODO_MINDIFF_NBITS); - } else fprintf(stderr,"cmp.%d mult.%d for ht.%d\n",mult>1,(int32_t)mult,(int32_t)pindexLast->GetHeight()); - } - if ( flag == 0 ) - { - bnSum4 = zawy_targetMA(easy,bnSum4,4,block4diff * 3,10); - bnSum7 = zawy_targetMA(easy,bnSum7,7,block7diff * 5,10); - bnSum12 = zawy_targetMA(easy,bnSum12,12,block12diff * 6,10); - if ( bnSum4 > bnSum7 ) - bnTmp = bnSum4; - else bnTmp = bnSum7; - if ( bnSum12 > bnTmp ) - bnTmp = bnSum12; - if ( bnTmp > bnTarget ) + origtarget = bnTarget; + past = 20; + if ( zflags[0] == 0 || zflags[0] == 3 ) + { + bnTarget = RT_CST_RST_outer(height,pblock->nTime,bnTarget,ts,ct,1,2,3,past); + if ( bnTarget < origtarget ) + zawyflag = 2; + else + { + bnTarget = RT_CST_RST_outer(height,pblock->nTime,bnTarget,ts,ct,7,3,6,past+10); + if ( bnTarget < origtarget ) + zawyflag = 2; + else + { + bnTarget = RT_CST_RST_outer(height,pblock->nTime,bnTarget,ts,ct,12,7,12,past+20); + if ( bnTarget < origtarget ) + zawyflag = 2; + } + } + } + else + { + for (i=0; i<40; i++) + if ( zflags[i] == 2 ) + break; + if ( i < 40 ) + { + bnTarget = RT_CST_RST_inner(height,pblock->nTime,bnTarget,ts,ct,3,i); + bnTarget6 = RT_CST_RST_inner(height,pblock->nTime,bnTarget,ts,ct,6,i); + bnTarget12 = RT_CST_RST_inner(height,pblock->nTime,bnTarget,ts,ct,12,i); + if ( bnTarget6 < bnTarget12 ) + bnTmp = bnTarget6; + else bnTmp = bnTarget12; + if ( bnTmp < bnTarget ) + bnTarget = bnTmp; + if ( bnTarget != origtarget ) + zawyflag = 1; + } + } + } + if ( mult > 1 ) // e^mult case, jl777: test of mult > 1 failed when it was int64_t??? { - fprintf(stderr,"ht.%d block12diff %d > %d, make easier\n",(int32_t)pindexLast->GetHeight()+1,block12diff,ASSETCHAINS_BLOCKTIME*13); - bnTarget = (bnTmp + bnPrev) / arith_uint256(2); - flag = 1; + origtarget = bnTarget; + bnTarget = zawy_exponential(bnTarget,mult); + if ( bnTarget < origtarget || bnTarget > easy ) + { + bnTarget = easy; + fprintf(stderr,"cmp.%d mult.%d ht.%d -> easy target\n",mult>1,(int32_t)mult,height); + return(KOMODO_MINDIFF_NBITS & (~3)); + } + { + int32_t z; + for (z=31; z>=0; z--) + fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[z]); + } + fprintf(stderr," exp() to the rescue cmp.%d mult.%d for ht.%d\n",mult>1,(int32_t)mult,height); + } + if ( 0 && zflags[0] == 0 && zawyflag == 0 && mult <= 1 ) + { + bnTarget = zawy_TSA_EMA(height,tipdiff,(bnTarget+ct[0]+ct[1])/arith_uint256(3),ts[0] - ts[1]); + if ( bnTarget < origtarget ) + zawyflag = 3; } } nbits = bnTarget.GetCompact(); + nbits = (nbits & 0xfffffffc) | zawyflag; } return(nbits); } diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index d70f198f1..741f02f7b 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -403,7 +403,52 @@ UniValue setgenerate(const UniValue& params, bool fHelp) } #endif +CBlockIndex *komodo_chainactive(int32_t height); +arith_uint256 zawy_ctB(arith_uint256 bnTarget,uint32_t solvetime); +UniValue genminingCSV(const UniValue& params, bool fHelp) +{ + int32_t i,z,height; uint32_t solvetime,prevtime=0; FILE *fp; char str[65],str2[65],fname[256]; uint256 hash; arith_uint256 bnTarget; CBlockIndex *pindex; bool fNegative,fOverflow; UniValue result(UniValue::VOBJ); + if (fHelp || params.size() != 0 ) + throw runtime_error("genminingCSV\n"); + LOCK(cs_main); + sprintf(fname,"%s_mining.csv",ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fprintf(fp,"height,nTime,nBits,bnTarget,bnTargetB,diff,solvetime\n"); + height = komodo_nextheight(); + for (i=0; inBits,&fNegative,&fOverflow); + solvetime = (prevtime==0) ? 0 : (int32_t)(pindex->nTime - prevtime); + for (z=0; z<16; z++) + sprintf(&str[z<<1],"%02x",((uint8_t *)&bnTarget)[31-z]); + str[32] = 0; + //hash = pindex->GetBlockHash(); + memset(&hash,0,sizeof(hash)); + if ( i >= 64 && (pindex->nBits & 3) != 0 ) + hash = ArithToUint256(zawy_ctB(bnTarget,solvetime)); + for (z=0; z<16; z++) + sprintf(&str2[z<<1],"%02x",((uint8_t *)&hash)[31-z]); + str2[32] = 0; fprintf(fp,"%d,%u,%08x,%s,%s,%.1f,%d\n",i,pindex->nTime,pindex->nBits,str,str2,GetDifficulty(pindex),solvetime); + prevtime = pindex->nTime; + } + } + fclose(fp); + result.push_back(Pair("result", "success")); + result.push_back(Pair("created", fname)); + } + else + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("error", "couldnt create mining.csv")); + result.push_back(Pair("filename", fname)); + } + return(result); +} + UniValue getmininginfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 6baa8a67d..24f6344ef 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -384,6 +384,7 @@ static const CRPCCommand vRPCCommands[] = { "mining", "prioritisetransaction", &prioritisetransaction, true }, { "mining", "submitblock", &submitblock, true }, { "mining", "getblocksubsidy", &getblocksubsidy, true }, + { "mining", "genminingCSV", &genminingCSV, true }, #ifdef ENABLE_MINING /* Coin generation */ diff --git a/src/rpc/server.h b/src/rpc/server.h index 6338989a5..f594b0fb5 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -463,6 +463,7 @@ extern UniValue importgatewaycompletesigning(const UniValue& params, bool fHelp) extern UniValue importgatewaymarkdone(const UniValue& params, bool fHelp); extern UniValue importgatewaypendingwithdraws(const UniValue& params, bool fHelp); extern UniValue importgatewayprocessed(const UniValue& params, bool fHelp); +extern UniValue genminingCSV(const UniValue& params, bool fHelp); extern UniValue nspv_getinfo(const UniValue& params, bool fHelp); extern UniValue nspv_login(const UniValue& params, bool fHelp);