}
// Scan given coins set for kernel solution
-bool ScanForStakeKernelHash(MetaMap &mapMeta, KernelSearchSettings &settings, CoinsSet::value_type &kernelcoin, unsigned int &nTimeTx, unsigned int &nBlockTime)
+bool ScanForStakeKernelHash(MetaMap &mapMeta, KernelSearchSettings &settings, CoinsSet::value_type &kernelcoin, unsigned int &nTimeTx, unsigned int &nBlockTime, uint64 &nKernelsTried, uint64 &nCoinDaysTried)
{
uint256 hashProofOfStake = 0;
// Calculate kernel hash
hashProofOfStake = Hash(ss.begin(), ss.end());
+ // Update statistics
+ nKernelsTried += 1;
+ nCoinDaysTried += bnCoinDayWeight.getuint64();
+
if (bnTargetProofOfStake >= CBigNum(hashProofOfStake))
{
if (fDebug)
typedef std::map<std::pair<uint256, unsigned int>, std::pair<std::pair<CTxIndex, std::pair<const CWalletTx*,unsigned int> >, std::pair<CBlock, uint64> > > MetaMap;
// Scan given coins set for kernel solution
-bool ScanForStakeKernelHash(MetaMap &mapMeta, KernelSearchSettings &settings, CoinsSet::value_type &kernelcoin, unsigned int &nTimeTx, unsigned int &nBlockTime);
+bool ScanForStakeKernelHash(MetaMap &mapMeta, KernelSearchSettings &settings, CoinsSet::value_type &kernelcoin, unsigned int &nTimeTx, unsigned int &nBlockTime, uint64 &nKernelsTried, uint64 &nCoinDaysTried);
// Check kernel hash target and coinstake signature
// Sets hashProofOfStake on success return
return;
}
- uint64 nMinWeight = 0, nMaxWeight = 0, nTotalWeight = 0;
- walletModel->getStakeWeight(nMinWeight, nMaxWeight, nTotalWeight);
+ float nKernelsRate = 0, nCoinDaysRate = 0;
+ walletModel->getStakeStats(nKernelsRate, nCoinDaysRate);
- if (nTotalWeight > 0)
+ if (nKernelsRate > 0)
{
labelMiningIcon->setPixmap(QIcon(":/icons/mining_active").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelMiningIcon->setToolTip(tr("Stake miner is active\nYour current stake weight is %1\nNetwork weight is %2\nAverage block generation time is %3").arg(nTotalWeight).arg(dNetworkWeight).arg(msg));
*/
- labelMiningIcon->setToolTip(tr("Stake miner is active\nYour current stake weight is %1\nNetwork weight is %2").arg(nTotalWeight).arg(nNetworkWeight));
+ labelMiningIcon->setToolTip(tr("Stake miner is active\nKernel rate is %1 k/s\nCD rate is %2 CD/s\nNetwork weight is %3").arg(nKernelsRate).arg(nCoinDaysRate).arg(nNetworkWeight));
}
else
labelMiningIcon->setToolTip(tr("No suitable inputs were found"));
return retval;
}
-void WalletModel::getStakeWeight(uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight)
+void WalletModel::getStakeStats(float &nKernelsRate, float &nCoinDaysRate)
{
- wallet->GetStakeWeight(*wallet, nMinWeight, nMaxWeight, nWeight);
+ wallet->GetStakeStats(nKernelsRate, nCoinDaysRate);
}
void WalletModel::getStakeWeightFromValue(const int64& nTime, const int64& nValue, uint64& nWeight)
bool dumpWallet(const QString &filename);
bool importWallet(const QString &filename);
- void getStakeWeight(quint64& nMinWeight, quint64& nMaxWeight, quint64& nWeight);
+ void getStakeStats(float &nKernelsRate, float &nCoinDaysRate);
void getStakeWeightFromValue(const qint64& nTime, const qint64& nValue, quint64& nWeight);
// RAI object for unlocking wallet, returned by requestUnlock()
"getmininginfo\n"
"Returns an object containing mining-related information.");
- uint64 nMinWeight = 0, nMaxWeight = 0, nWeight = 0;
- pwalletMain->GetStakeWeight(*pwalletMain, nMinWeight, nMaxWeight, nWeight);
+ float nKernelsRate = 0, nCoinDaysRate = 0;
+ pwalletMain->GetStakeStats(nKernelsRate, nCoinDaysRate);
Object obj, diff, weight;
obj.push_back(Pair("blocks", (int)nBestHeight));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
- weight.push_back(Pair("minimum", (uint64_t)nMinWeight));
- weight.push_back(Pair("maximum", (uint64_t)nMaxWeight));
- weight.push_back(Pair("combined", (uint64_t)nWeight));
- obj.push_back(Pair("stakeweight", weight));
+ weight.push_back(Pair("kernelsrate", nKernelsRate));
+ weight.push_back(Pair("cdaysrate", nCoinDaysRate));
+ obj.push_back(Pair("stakestats", weight));
obj.push_back(Pair("stakeinterest", (uint64_t)GetProofOfStakeReward(0, GetLastBlockIndex(pindexBest, true)->nBits, GetLastBlockIndex(pindexBest, true)->nTime, true)));
obj.push_back(Pair("testnet", fTestNet));
* any later version. See COPYING for more details.
*/
-#if defined(__linux__) && defined(__ELF__)
- .section .note.GNU-stack,"",%progbits
-#endif
-
#if defined(__arm__) && defined(__APCS_32__)
.macro salsa8_core_doubleround_body
}
-// NovaCoin: get current stake weight
-bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight)
+// NovaCoin: get current stake miner statistics
+void CWallet::GetStakeStats(float &nKernelsRate, float &nCoinDaysRate)
{
- // Choose coins to use
- int64 nBalance = GetBalance();
- int64 nReserveBalance = 0;
+ static uint64 nLastKernels = 0, nLastCoinDays = 0;
+ static float nLastKernelsRate = 0, nLastCoinDaysRate = 0;
+ static unsigned int nLastTime = GetTime();
- if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance))
- return error("CreateCoinStake : invalid reserve balance amount");
- if (nBalance <= nReserveBalance)
- return false;
-
- CTxDB txdb("r");
+ if (nKernelsTried < nLastKernels)
{
- LOCK2(cs_main, cs_wallet);
- // Cache outputs unless best block or wallet transaction set changed
- if (!fCoinsDataActual)
- {
- mapMeta.clear();
- int64 nValueIn = 0;
- CoinsSet setCoins;
- if (!SelectCoinsSimple(nBalance - nReserveBalance, MIN_TX_FEE, MAX_MONEY, GetAdjustedTime(), nCoinbaseMaturity * 10, setCoins, nValueIn))
- return false;
+ nLastKernels = 0;
+ nLastCoinDays = 0;
- if (setCoins.empty())
- return false;
-
- {
- CTxIndex txindex;
- CBlock block;
- for(CoinsSet::iterator pcoin = setCoins.begin(); pcoin != setCoins.end(); pcoin++)
- {
- // Load transaction index item
- if (!txdb.ReadTxIndex(pcoin->first->GetHash(), txindex))
- continue;
-
- // Read block header
- if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
- continue;
-
- uint64 nStakeModifier = 0;
- if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier))
- continue;
-
- // Add meta record
- // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier))
- mapMeta[make_pair(pcoin->first->GetHash(), pcoin->second)] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier));
-
- if (fDebug)
- printf("Load coin: %s\n", pcoin->first->GetHash().GetHex().c_str());
- }
- }
-
- if (fDebug)
- printf("Get stake weight: %"PRIszu" meta items loaded for %"PRIszu" coins\n", mapMeta.size(), setCoins.size());
-
- fCoinsDataActual = true;
- }
+ nLastTime = GetTime();
}
-
- // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier))
- for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++)
+ unsigned int nInterval = GetTime() - nLastTime;
+ if (nKernelsTried > 1000 && nInterval > 5)
{
- // Get coin
- CoinsSet::value_type pcoin = meta_item->second.first.second;
-
- int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)GetTime());
- CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60);
-
- // Weight is greater than zero
- if (nTimeWeight > 0)
- {
- nWeight += bnCoinDayWeight.getuint64();
- }
-
- // Weight is greater than zero, but the maximum value isn't reached yet
- if (nTimeWeight > 0 && nTimeWeight < nStakeMaxAge)
- {
- nMinWeight += bnCoinDayWeight.getuint64();
- }
+ nKernelsRate = nLastKernelsRate = ( nKernelsTried - nLastKernels ) / (float) nInterval;
+ nCoinDaysRate = nLastCoinDaysRate = ( nCoinDaysTried - nLastCoinDays ) / (float) nInterval;
- // Maximum weight was reached
- if (nTimeWeight == nStakeMaxAge)
- {
- nMaxWeight += bnCoinDayWeight.getuint64();
- }
+ nLastKernels = nKernelsTried;
+ nLastCoinDays = nCoinDaysTried;
+ nLastTime = GetTime();
+ }
+ else
+ {
+ nKernelsRate = nLastKernelsRate;
+ nCoinDaysRate = nLastCoinDaysRate;
}
-
- return true;
}
bool CWallet::MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nOutputValue, list<uint256>& listMerged)
printf("Stake miner: %"PRIszu" meta items loaded for %"PRIszu" coins\n", mapMeta.size(), setCoins.size());
fCoinsDataActual = true;
+ nKernelsTried = 0;
+ nCoinDaysTried = 0;
}
}
COutPoint prevoutStake;
CoinsSet::value_type kernelcoin;
- if (ScanForStakeKernelHash(mapMeta, settings, kernelcoin, nTimeTx, nBlockTime))
+ if (ScanForStakeKernelHash(mapMeta, settings, kernelcoin, nTimeTx, nBlockTime, nKernelsTried, nCoinDaysTried))
{
// Found a kernel
if (fDebug && GetBoolArg("-printcoinstake"))
// selected coins metadata
std::map<std::pair<uint256, unsigned int>, std::pair<std::pair<CTxIndex, std::pair<const CWalletTx*,unsigned int> >, std::pair<CBlock, uint64> > > mapMeta;
+ // stake mining statistics
+ uint64 nKernelsTried;
+ uint64 nCoinDaysTried;
+
public:
mutable CCriticalSection cs_wallet;
nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
nOrderPosNext = 0;
+ nKernelsTried = 0;
+ nCoinDaysTried = 0;
}
CWallet(std::string strWalletFileIn)
{
nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
nOrderPosNext = 0;
+ nKernelsTried = 0;
+ nCoinDaysTried = 0;
}
std::map<uint256, CWalletTx> mapWallet;
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
- bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight);
+ void GetStakeStats(float &nKernelsRate, float &nCoinDaysRate);
void GetStakeWeightFromValue(const int64& nTime, const int64& nValue, uint64& nWeight);
bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew, CKey& key);
bool MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nMaxValue, std::list<uint256>& listMerged);