From 9d519fcff4e11f4e770c350fa69c302aed881b01 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 18 Aug 2013 00:44:39 +0400 Subject: [PATCH] Update getmininginfo * More correct DayWeight calculation for local stakes * Network stake weight calculation precision improvement * Passive weight isn't calculated anymore --- src/rpcmining.cpp | 35 +++++++++++++++++++++++++---------- src/wallet.cpp | 44 ++++++++++++++++++++++++++++---------------- src/wallet.h | 5 ++--- 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index d71df69..fe8cf0b 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -18,13 +18,13 @@ Value getmininginfo(const Array& params, bool fHelp) "getmininginfo\n" "Returns an object containing mining-related information."); - int64 nTargetSpacingWorkMin = 30; - int64 nTargetSpacingWork = nTargetSpacingWorkMin; - int64 nPoWInterval = 72; - int64 nTargetSpacingStake = 600; + double dStakeKernelsTriedAvg = 0; + int nPoWInterval = 72, nPoSInterval = 72, nStakesHandled = 0, nStakesTime = 0; + int64 nTargetSpacingWorkMin = 30, nTargetSpacingWork = 30; CBlockIndex* pindex = pindexGenesisBlock; CBlockIndex* pindexPrevWork = pindexGenesisBlock; + CBlockIndex* pindexPrevStake = NULL; while (pindex) { @@ -39,8 +39,24 @@ Value getmininginfo(const Array& params, bool fHelp) pindex = pindex->pnext; } + + pindex = pindexBest; + + while (pindex && nStakesHandled < nPoSInterval) + { + if (pindex->IsProofOfStake()) + { + dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296; + nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; + pindexPrevStake = pindex; + nStakesHandled++; + } + + pindex = pindex->pprev; + } + double dNetworkMhps = GetDifficulty() * 4294.967296 / nTargetSpacingWork; - int nNetworkWeight = GetDifficulty(GetLastBlockIndex(pindexBest, true)) * 4294967296 / nTargetSpacingStake; + double dNetworkWeight = dStakeKernelsTriedAvg / nStakesTime; Object obj; obj.push_back(Pair("blocks", (int)nBestHeight)); @@ -49,13 +65,12 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits))); obj.push_back(Pair("netmhashps", dNetworkMhps)); - obj.push_back(Pair("netstakeweight", (uint64_t) nNetworkWeight)); + obj.push_back(Pair("netstakeweight", dNetworkWeight)); obj.push_back(Pair("errors", GetWarnings("statusbar"))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); - obj.push_back(Pair("stakeweight", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain, STAKE_NORMAL))); - obj.push_back(Pair("minweight", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain, STAKE_MINWEIGHT))); - obj.push_back(Pair("maxweight", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain, STAKE_MAXWEIGHT))); - obj.push_back(Pair("passiveweight", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain, STAKE_BELOWMIN))); + obj.push_back(Pair("stakeweight", (uint64_t)pwalletMain->GetStakeWeight(*pwalletMain, STAKE_NORMAL))); + obj.push_back(Pair("minweight", (uint64_t)pwalletMain->GetStakeWeight(*pwalletMain, STAKE_MINWEIGHT))); + obj.push_back(Pair("maxweight", (uint64_t)pwalletMain->GetStakeWeight(*pwalletMain, STAKE_MAXWEIGHT))); obj.push_back(Pair("stakeinterest", (uint64_t)GetProofOfStakeReward(0, GetLastBlockIndex(pindexBest, true)->nBits, GetLastBlockIndex(pindexBest, true)->nTime, true))); obj.push_back(Pair("testnet", fTestNet)); return obj; diff --git a/src/wallet.cpp b/src/wallet.cpp index 35d24b5..df32644 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1368,8 +1368,8 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet); } -// NovaCoin: get current stake generation power -uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore, enum StakeWeightMode mode) +// NovaCoin: get current stake weight +uint64 CWallet::GetStakeWeight(const CKeyStore& keystore, enum StakeWeightMode mode) { LOCK2(cs_main, cs_wallet); @@ -1380,7 +1380,7 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore, enum StakeWeightMod if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) { - error("GetStakeMintPower : invalid reserve balance amount"); + error("GetStakeWeight : invalid reserve balance amount"); return 0; } @@ -1402,41 +1402,53 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore, enum StakeWeightMod if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) continue; + unsigned int nTime = pcoin.first->nTime; + switch(mode) { case STAKE_NORMAL: // Do not count input that is still less than 30 days old - if (pcoin.first->nTime + nStakeMinAge > GetTime()) + if (nTime + nStakeMinAge > GetTime()) continue; break; case STAKE_MAXWEIGHT: // Do not count input that is still less than 90 days old - if (pcoin.first->nTime + nStakeMaxAge > GetTime()) + if (nTime + nStakeMaxAge > GetTime()) continue; break; case STAKE_MINWEIGHT: // Count only inputs with suitable age (from 30 to 90 days old) - if (pcoin.first->nTime + nStakeMaxAge < GetTime()) - continue; - if (pcoin.first->nTime + nStakeMinAge > GetTime()) + if (nTime + nStakeMaxAge < GetTime()) continue; - break; - case STAKE_BELOWMIN: - // Count only inputs with suitable age (less than 30 days old) - if (pcoin.first->nTime + nStakeMinAge < GetTime()) + if (nTime + nStakeMinAge > GetTime()) continue; break; } - CBigNum bnCentSecond = CBigNum(pcoin.first->vout[pcoin.second].nValue) * (GetTime()-pcoin.first->nTime) / CENT; - CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60); + int64 nTimeWeight; + + // Kernel hash weight starts from 0 at the 30-day min age + // this change increases active coins participating the hash and helps + // to secure the network when proof-of-stake difficulty is low + // + if(fTestNet || (STAKEWEIGHT_SWITCH_TIME < nTime)) + { + // New rule since 01 Jan 2014: Maximum TimeWeight is 90 days. + nTimeWeight = min((int64)GetTime() - nTime - nStakeMinAge, (int64)nStakeMaxAge); + } + else + { + // Current rule: Maximum TimeWeight is 60 days. + nTimeWeight = min((int64)GetTime() - nTime, (int64)nStakeMaxAge) - nStakeMinAge; + } + CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60); - nCoinAge += bnCoinDay.getuint64(); + nCoinAge += bnCoinDayWeight.getuint64(); } if (fDebug && GetBoolArg("-printcoinage")) - printf("StakePower bnCoinDay=%"PRI64d"\n", nCoinAge); + printf("StakeWeight bnCoinDay=%"PRI64d"\n", nCoinAge); return nCoinAge; } diff --git a/src/wallet.h b/src/wallet.h index 9fc58d5..39cd1ce 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -40,8 +40,7 @@ enum StakeWeightMode { STAKE_NORMAL = 0, // all 30+ days old inputs STAKE_MAXWEIGHT = 1, // only 90+ days old inputs - STAKE_MINWEIGHT = 3, // only [30-90] days old inputs - STAKE_BELOWMIN = 4 // only less than 30 days old inputs + STAKE_MINWEIGHT = 3 // only [30-90] days old inputs }; /** A key pool entry */ @@ -193,7 +192,7 @@ public: bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); - uint64 GetStakeMintPower(const CKeyStore& keystore, enum StakeWeightMode mode=STAKE_NORMAL); + uint64 GetStakeWeight(const CKeyStore& keystore, enum StakeWeightMode mode=STAKE_NORMAL); bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); -- 1.7.1