double GetPoSKernelPS() { int nPoSInterval = 72; double dStakeKernelsTriedAvg = 0; int nStakesHandled = 0, nStakesTime = 0; CBlockIndex* pindex = pindexBest;; CBlockIndex* pindexPrevStake = NULL; while (pindex && nStakesHandled < nPoSInterval) { if (pindex->IsProofOfStake()) { dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0; nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; pindexPrevStake = pindex; nStakesHandled++; } pindex = pindex->pprev; } double result = 0; if (nStakesTime) result = dStakeKernelsTriedAvg / nStakesTime; return result; }
double GetPoSKernelPS() { int nPoSInterval = 72; double dStakeKernelsTriedAvg = 0; int nStakesHandled = 0, nStakesTime = 0; CBlockIndex* pindex = pindexBest;; CBlockIndex* pindexPrevStake = NULL; while (pindex && nStakesHandled < nPoSInterval) { if (pindex->IsProofOfStake()) { if (pindexPrevStake) { dStakeKernelsTriedAvg += GetDifficulty(pindexPrevStake) * 4294967296.0; nStakesTime += pindexPrevStake->nTime - pindex->nTime; nStakesHandled++; } pindexPrevStake = pindex; } pindex = pindex->pprev; } double result = 0; if (nStakesTime) result = dStakeKernelsTriedAvg / nStakesTime; if (IsProtocolV2(nBestHeight)) result *= STAKE_TIMESTAMP_MASK + 1; return result; }
double GetPoSKernelPS() { int nPoSInterval = 72; if (!fTestNet){ if (pindexBest->nHeight >= KGW_FORK_BLOCK) { nPoSInterval = 144; } } double dStakeKernelsTriedAvg = 0; int nStakesHandled = 0, nStakesTime = 0; CBlockIndex* pindex = pindexBest;; CBlockIndex* pindexPrevStake = NULL; while (pindex && nStakesHandled < nPoSInterval) { if (pindex->IsProofOfStake()) { dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0; nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; pindexPrevStake = pindex; nStakesHandled++; } pindex = pindex->pprev; } return nStakesTime ? dStakeKernelsTriedAvg / nStakesTime : 0; }
double GetPoSKernelPS() { int nPoSInterval = 72; double dStakeKernelsTriedAvg = 0; int nStakesHandled = 0, nStakesTime = 0; if (nNodeMode == NT_THIN) { CBlockThinIndex* pindex = pindexBestHeader;; CBlockThinIndex* pindexPrevStake = NULL; while (pindex && nStakesHandled < nPoSInterval) { if (pindex->IsProofOfStake()) { if (pindexPrevStake) { dStakeKernelsTriedAvg += GetHeaderDifficulty(pindex) * 4294967296.0; nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; nStakesHandled++; }; pindexPrevStake = pindex; }; pindex = pindex->pprev; }; } else { CBlockIndex* pindex = pindexBest;; CBlockIndex* pindexPrevStake = NULL; while (pindex && nStakesHandled < nPoSInterval) { if (pindex->IsProofOfStake()) { if (pindexPrevStake) { dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0; nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; nStakesHandled++; }; pindexPrevStake = pindex; }; pindex = pindex->pprev; }; }; double result = 0; if (nStakesTime) result = dStakeKernelsTriedAvg / nStakesTime; if (Params().IsProtocolV2(nBestHeight)) result *= STAKE_TIMESTAMP_MASK + 1; return result; }
bool CTxDB::LoadBlockIndex() { // Get database cursor Dbc* pcursor = GetCursor(); if (!pcursor) return false; // Load mapBlockIndex unsigned int fFlags = DB_SET_RANGE; for (;;) { // Read next record CDataStream ssKey(SER_DISK, CLIENT_VERSION); if (fFlags == DB_SET_RANGE) ssKey << make_pair(string("blockindex"), uint256(0)); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); fFlags = DB_NEXT; if (ret == DB_NOTFOUND) break; else if (ret != 0) return false; // Unserialize try { string strType; ssKey >> strType; if (strType == "blockindex" && !fRequestShutdown) { CDiskBlockIndex diskindex; ssValue >> diskindex; // Construct block index object CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); pindexNew->nFile = diskindex.nFile; pindexNew->nBlockPos = diskindex.nBlockPos; pindexNew->nHeight = diskindex.nHeight; pindexNew->nMint = diskindex.nMint; pindexNew->nMoneySupply = diskindex.nMoneySupply; pindexNew->nFlags = diskindex.nFlags; pindexNew->nStakeModifier = diskindex.nStakeModifier; pindexNew->prevoutStake = diskindex.prevoutStake; pindexNew->nStakeTime = diskindex.nStakeTime; pindexNew->hashProofOfStake = diskindex.hashProofOfStake; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; // Watch for genesis block if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) pindexGenesisBlock = pindexNew; if (!pindexNew->CheckIndex()) return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); // paycoin: build setStakeSeen if (pindexNew->IsProofOfStake()) setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); } else { break; // if shutdown requested or finished loading block index } } // try catch (std::exception &e) {
bool CTxDB::LoadBlockIndex() { if (mapBlockIndex.size() > 0) { // Already loaded once in this session. It can happen during migration // from BDB. return true; } // The block index is an in-memory structure that maps hashes to on-disk // locations where the contents of the block can be found. Here, we scan it // out of the DB and into mapBlockIndex. leveldb::Iterator *iterator = pdb->NewIterator(leveldb::ReadOptions()); // Seek to start key. CDataStream ssStartKey(SER_DISK, CLIENT_VERSION); ssStartKey << make_pair(string("blockindex"), uint256(0)); iterator->Seek(ssStartKey.str()); // Now read each entry. while (iterator->Valid()) { // Unpack keys and values. CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.write(iterator->key().data(), iterator->key().size()); CDataStream ssValue(SER_DISK, CLIENT_VERSION); ssValue.write(iterator->value().data(), iterator->value().size()); string strType; ssKey >> strType; // Did we reach the end of the data to read? if (fRequestShutdown || strType != "blockindex") break; CDiskBlockIndex diskindex; ssValue >> diskindex; uint256 blockHash = diskindex.GetBlockHash(); // Construct block index object CBlockIndex* pindexNew = InsertBlockIndex(blockHash); pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); pindexNew->nFile = diskindex.nFile; pindexNew->nBlockPos = diskindex.nBlockPos; pindexNew->nHeight = diskindex.nHeight; pindexNew->nMint = diskindex.nMint; pindexNew->nMoneySupply = diskindex.nMoneySupply; pindexNew->nFlags = diskindex.nFlags; pindexNew->nStakeModifier = diskindex.nStakeModifier; pindexNew->prevoutStake = diskindex.prevoutStake; pindexNew->nStakeTime = diskindex.nStakeTime; pindexNew->hashProofOfStake = diskindex.hashProofOfStake; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; // Watch for genesis block if (pindexGenesisBlock == NULL && blockHash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) pindexGenesisBlock = pindexNew; if (!pindexNew->CheckIndex()) { delete iterator; return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); } // CurrentCoin: build setStakeSeen if (pindexNew->IsProofOfStake()) setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); iterator->Next(); } delete iterator; if (fRequestShutdown) return true; // Calculate nChainTrust vector<pair<int, CBlockIndex*> > vSortedByHeight; vSortedByHeight.reserve(mapBlockIndex.size()); BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) { CBlockIndex* pindex = item.second; vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); } sort(vSortedByHeight.begin(), vSortedByHeight.end()); BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) { CBlockIndex* pindex = item.second; pindex->nChainTrust = (pindex->pprev ? pindex->pprev->nChainTrust : 0) + pindex->GetBlockTrust(); // CurrentCoin: calculate stake modifier checksum pindex->nStakeModifierChecksum = GetStakeModifierChecksum(pindex); if (!CheckStakeModifierCheckpoints(pindex->nHeight, pindex->nStakeModifierChecksum)) return error("CTxDB::LoadBlockIndex() : Failed stake modifier checkpoint height=%d, modifier=0x%016"PRI64x, pindex->nHeight, pindex->nStakeModifier); } // Load hashBestChain pointer to end of best chain if (!ReadHashBestChain(hashBestChain)) { if (pindexGenesisBlock == NULL) return true; return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded"); } if (!mapBlockIndex.count(hashBestChain)) return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index"); pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; nBestChainTrust = pindexBest->nChainTrust; printf("LoadBlockIndex(): hashBestChain=%s height=%d trust=%s date=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, CBigNum(nBestChainTrust).ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); // CurrentCoin: load hashSyncCheckpoint if (!ReadSyncCheckpoint(Checkpoints::hashSyncCheckpoint)) return error("CTxDB::LoadBlockIndex() : hashSyncCheckpoint not loaded"); printf("LoadBlockIndex(): synchronized checkpoint %s\n", Checkpoints::hashSyncCheckpoint.ToString().c_str()); // Load bnBestInvalidTrust, OK if it doesn't exist CBigNum bnBestInvalidTrust; ReadBestInvalidTrust(bnBestInvalidTrust); nBestInvalidTrust = bnBestInvalidTrust.getuint256(); // Verify blocks in the best chain int nCheckLevel = GetArg("-checklevel", 1); int nCheckDepth = GetArg( "-checkblocks", 2500); if (nCheckDepth == 0) nCheckDepth = 1000000000; // suffices until the year 19000 if (nCheckDepth > nBestHeight) nCheckDepth = nBestHeight; printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); CBlockIndex* pindexFork = NULL; map<pair<unsigned int, unsigned int>, CBlockIndex*> mapBlockPos; for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) { if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; CBlock block; if (!block.ReadFromDisk(pindex)) return error("LoadBlockIndex() : block.ReadFromDisk failed"); // check level 1: verify block validity // check level 7: verify block signature too if (nCheckLevel>0 && !block.CheckBlock(true, true, (nCheckLevel>6))) { printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); pindexFork = pindex->pprev; } // check level 2: verify transaction index validity if (nCheckLevel>1) { pair<unsigned int, unsigned int> pos = make_pair(pindex->nFile, pindex->nBlockPos); mapBlockPos[pos] = pindex; BOOST_FOREACH(const CTransaction &tx, block.vtx) { uint256 hashTx = tx.GetHash(); CTxIndex txindex; if (ReadTxIndex(hashTx, txindex)) { // check level 3: checker transaction hashes if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos) { // either an error or a duplicate transaction CTransaction txFound; if (!txFound.ReadFromDisk(txindex.pos)) { printf("LoadBlockIndex() : *** cannot read mislocated transaction %s\n", hashTx.ToString().c_str()); pindexFork = pindex->pprev; } else if (txFound.GetHash() != hashTx) // not a duplicate tx { printf("LoadBlockIndex(): *** invalid tx position for %s\n", hashTx.ToString().c_str()); pindexFork = pindex->pprev; } } // check level 4: check whether spent txouts were spent within the main chain unsigned int nOutput = 0; if (nCheckLevel>3) { BOOST_FOREACH(const CDiskTxPos &txpos, txindex.vSpent) { if (!txpos.IsNull()) { pair<unsigned int, unsigned int> posFind = make_pair(txpos.nFile, txpos.nBlockPos); if (!mapBlockPos.count(posFind)) { printf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), hashTx.ToString().c_str()); pindexFork = pindex->pprev; } // check level 6: check whether spent txouts were spent by a valid transaction that consume them if (nCheckLevel>5) { CTransaction txSpend; if (!txSpend.ReadFromDisk(txpos)) { printf("LoadBlockIndex(): *** cannot read spending transaction of %s:%i from disk\n", hashTx.ToString().c_str(), nOutput); pindexFork = pindex->pprev; } else if (!txSpend.CheckTransaction()) { printf("LoadBlockIndex(): *** spending transaction of %s:%i is invalid\n", hashTx.ToString().c_str(), nOutput); pindexFork = pindex->pprev; } else { bool fFound = false; BOOST_FOREACH(const CTxIn &txin, txSpend.vin) if (txin.prevout.hash == hashTx && txin.prevout.n == nOutput) fFound = true; if (!fFound) { printf("LoadBlockIndex(): *** spending transaction of %s:%i does not spend it\n", hashTx.ToString().c_str(), nOutput); pindexFork = pindex->pprev; } } } } nOutput++; } } }
Value getmininginfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( "getmininginfo\n" "Returns an object containing mining-related information."); double dStakeKernelsTriedAvg = 0; int nPoWInterval = 72, nPoSInterval = 72, nStakesHandled = 0, nStakesTime = 0; int64 nTargetSpacingWorkMin = 2, nTargetSpacingWork = 2; CBlockIndex* pindex = pindexGenesisBlock; CBlockIndex* pindexPrevWork = pindexGenesisBlock; CBlockIndex* pindexPrevStake = NULL; while (pindex) { if (pindex->IsProofOfWork()) { int64 nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime(); nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1); nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin); pindexPrevWork = pindex; } 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; double dNetworkWeight = dStakeKernelsTriedAvg / nStakesTime; Object obj; obj.push_back(Pair("blocks", (int)nBestHeight)); obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize)); obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); //obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits))); //obj.push_back(Pair("powmhashps", dNetworkMhps)); 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("belowweight", (uint64_t)pwalletMain->GetStakeWeight(*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("StakeReadytunes", ((uint64_t)pwalletMain->GetStakeWeight(*pwalletMain, STAKE_NORMAL))/730)); //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; }
void ProfitExplorerPage::loadStakeChart(bool firstRun) { if(fShutdown) return; nTimeData.clear(); netStakeData.clear(); myStakeData.clear(); difficultyData.clear(); velTimeData.clear(); velAmountData.clear(); // go back this many blocks max int max = ui->spinBox->value(); int i = 0; //BOOST_REVERSE_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& b, mapBlockIndex) //{ // if(i >= max) // break; CBlockIndex* pindex = pindexBest; while(i < max && pindex != NULL) { //CBlockIndex* pindex = b.second; if(pindex->IsProofOfStake()) { nTimeData.append(pindex->nTime); netStakeData.append(pindex->nMint / COIN); // Read the block in and check if the coinstake is ours CBlock block; block.ReadFromDisk(pindex, true); if(block.IsProofOfStake()) // this should always be true here { velTimeData.append(pindex->nTime); double blockOutAmount = 0; for(int j=0; j<block.vtx.size(); j++) { blockOutAmount += block.vtx[j].GetValueOut() / COIN; } velAmountData.append(blockOutAmount); difficultyData.append(GetDifficulty(pindex)); if(pwalletMain->IsMine(block.vtx[1])) { myStakeData.append(pindex->nMint / COIN); } else { myStakeData.append(0); } } else { myStakeData.append(0); // should never happen } i = i + 1; } pindex = pindex->pprev; //++i; } if(!firstRun) { uint64_t nMinWeight = 0, nMaxWeight = 0, nWeight = 0; pwalletMain->GetStakeWeight(*pwalletMain, nMinWeight, nMaxWeight, nWeight); uint64_t nNetworkWeight = 0; if(pindexBest) nNetworkWeight = GetPoSKernelPS(); bool staking = nLastCoinStakeSearchInterval && nWeight; int nExpectedTime = staking ? (nTargetSpacing * nNetworkWeight / nWeight) : -1; ui->stakingLabel->setText(staking ? "Enabled" : "Disabled"); if(pindexBest) ui->difficultyLabel->setText(QString::number(GetDifficulty(GetLastBlockIndex(pindexBest, true)))); ui->weightLabel->setText(QString::number(nWeight)); ui->netWeightLabel->setText(QString::number(nNetworkWeight)); ui->timeToStakeLabel->setText(QString::number(nExpectedTime) + " secs"); } //qDebug() << "Stake blocks processed:"; //qDebug() << i; ui->customPlot->clearPlottables(); ui->customPlot->clearGraphs(); ui->customPlot->clearItems(); ui->customPlot->addGraph(); ui->customPlot->graph(0)->setPen(QPen(QColor(206, 206, 206))); // line color green for first graph ui->customPlot->graph(0)->setBrush(QBrush(QColor(206, 206, 206, 20))); // first graph will be filled with translucent green ui->customPlot->addGraph(); ui->customPlot->graph(1)->setPen(QPen(QColor(76, 255, 0))); // line color red for second graph ui->customPlot->graph(1)->setBrush(QBrush(QColor(76, 255, 0, 20))); if(ui->networkCheckBox->isChecked()) ui->customPlot->graph(0)->setData(nTimeData, netStakeData); ui->customPlot->graph(1)->setData(nTimeData, myStakeData); //ui->customPlot->xAxis->setRangeLower(nTimeData.first()); //ui->customPlot->xAxis->setRangeUpper(nTimeData.last()); QLinearGradient plotGradient; plotGradient.setStart(0, 0); plotGradient.setFinalStop(0, 350); plotGradient.setColorAt(0, QColor(10, 10, 10)); plotGradient.setColorAt(1, QColor(0, 0, 0)); ui->customPlot->setBackground(plotGradient); ui->customPlot->xAxis->grid()->setVisible(false); ui->customPlot->yAxis->grid()->setVisible(false); ui->customPlot->xAxis->grid()->setSubGridVisible(false); ui->customPlot->yAxis->grid()->setSubGridVisible(false); ui->customPlot->xAxis->setAutoTickStep(true); ui->customPlot->xAxis->setTickStep(3600 * 24); // 24 hr tickstep ui->customPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime); ui->customPlot->xAxis->setDateTimeSpec(Qt::UTC); ui->customPlot->xAxis->setDateTimeFormat("dd. MMM hh:mm"); ui->customPlot->xAxis->setTickLabelRotation(15); ui->customPlot->xAxis->setTickLabelColor(QColor(137, 140, 146)); ui->customPlot->yAxis->setTickLabelColor(QColor(137, 140, 146)); ui->customPlot->rescaleAxes(); ui->customPlot->xAxis->setLabelColor(QColor(137, 140, 146)); ui->customPlot->yAxis->setLabelColor(QColor(137, 140, 146)); ui->customPlot->yAxis->setLabel("$XQN Minted"); ui->customPlot->xAxis->setLabel("Stake Block Generation Time"); ui->customPlot->replot(); ui->difficultyPlot->clearPlottables(); ui->difficultyPlot->clearGraphs(); ui->difficultyPlot->clearItems(); ui->difficultyPlot->addGraph(); ui->difficultyPlot->graph(0)->setPen(QPen(QColor(76, 255, 0))); // line color green for first graph ui->difficultyPlot->graph(0)->setBrush(QBrush(QColor(76, 255, 0, 20))); // first graph will be filled with translucent green ui->difficultyPlot->graph(0)->setData(nTimeData, difficultyData); ui->difficultyPlot->xAxis->setRangeLower(nTimeData.first()); ui->difficultyPlot->xAxis->setRangeUpper(nTimeData.last()); QLinearGradient diffPlotGradient; diffPlotGradient.setStart(0, 0); diffPlotGradient.setFinalStop(0, 350); diffPlotGradient.setColorAt(0, QColor(10, 10, 10)); diffPlotGradient.setColorAt(1, QColor(0, 0, 0)); ui->difficultyPlot->setBackground(diffPlotGradient); ui->difficultyPlot->xAxis->grid()->setVisible(false); ui->difficultyPlot->yAxis->grid()->setVisible(false); ui->difficultyPlot->xAxis->grid()->setSubGridVisible(false); ui->difficultyPlot->yAxis->grid()->setSubGridVisible(false); ui->difficultyPlot->xAxis->setAutoTickStep(false); ui->difficultyPlot->xAxis->setTickStep(3600 * 24); // 24 hr tickstep ui->difficultyPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime); ui->difficultyPlot->xAxis->setDateTimeSpec(Qt::UTC); ui->difficultyPlot->xAxis->setDateTimeFormat("dd. MMM hh:mm"); ui->difficultyPlot->xAxis->setTickLabelRotation(15); ui->difficultyPlot->xAxis->setTickLabelColor(QColor(137, 140, 146)); ui->difficultyPlot->yAxis->setTickLabelColor(QColor(137, 140, 146)); ui->difficultyPlot->rescaleAxes(); ui->difficultyPlot->yAxis->setTickStep(0.00005); ui->difficultyPlot->xAxis->setLabelColor(QColor(137, 140, 146)); ui->difficultyPlot->yAxis->setLabelColor(QColor(137, 140, 146)); ui->difficultyPlot->yAxis->setLabel("Difficulty"); ui->difficultyPlot->xAxis->setTickLabels(false); //ui->difficultyPlot->xAxis->setLabel("Stake Block Generation Time"); ui->difficultyPlot->replot(); ui->velocityPlot->clearPlottables(); ui->velocityPlot->clearGraphs(); ui->velocityPlot->clearItems(); ui->velocityPlot->addGraph(); ui->velocityPlot->graph(0)->setPen(QPen(QColor(76, 255, 0))); // line color green for first graph ui->velocityPlot->graph(0)->setBrush(QBrush(QColor(76, 255, 0, 20))); // first graph will be filled with translucent green ui->velocityPlot->graph(0)->setData(velTimeData, velAmountData); ui->velocityPlot->xAxis->setRangeLower(velTimeData.first()); ui->velocityPlot->xAxis->setRangeUpper(velTimeData.last()); QLinearGradient velPlotGradient; velPlotGradient.setStart(0, 0); velPlotGradient.setFinalStop(0, 150); velPlotGradient.setColorAt(0, QColor(10, 10, 10)); velPlotGradient.setColorAt(1, QColor(0, 0, 0)); ui->velocityPlot->setBackground(velPlotGradient); ui->velocityPlot->xAxis->grid()->setVisible(false); ui->velocityPlot->yAxis->grid()->setVisible(false); ui->velocityPlot->xAxis->grid()->setSubGridVisible(false); ui->velocityPlot->yAxis->grid()->setSubGridVisible(false); ui->velocityPlot->xAxis->setAutoTickStep(false); ui->velocityPlot->xAxis->setTickStep(3600 * 24); // 24 hr tickstep ui->velocityPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime); ui->velocityPlot->xAxis->setDateTimeSpec(Qt::UTC); ui->velocityPlot->xAxis->setDateTimeFormat("dd. MMM hh:mm"); ui->velocityPlot->xAxis->setTickLabelRotation(15); ui->velocityPlot->xAxis->setTickLabelColor(QColor(137, 140, 146)); ui->velocityPlot->yAxis->setTickLabelColor(QColor(137, 140, 146)); ui->velocityPlot->yAxis->setScaleType(QCPAxis::stLogarithmic); ui->velocityPlot->yAxis->setTickStep(1000); ui->velocityPlot->xAxis->setLabelColor(QColor(137, 140, 146)); ui->velocityPlot->yAxis->setLabelColor(QColor(137, 140, 146)); ui->velocityPlot->yAxis->setLabel("$XQN"); ui->velocityPlot->xAxis->setTickLabels(false); ui->velocityPlot->xAxis->setLabel("Financial Velocity"); ui->velocityPlot->rescaleAxes(); ui->velocityPlot->replot(); }
bool CTxDB::LoadBlockIndex() { if (mapBlockIndex.size() > 0) { // Already loaded once in this session. It can happen during migration // from BDB. return true; } #ifdef WIN32 const int #ifdef _DEBUG nREFRESH = 2000; // generally resfresh rates are chosen to give ~1 update/sec #else // seems to be slowing down?? nREFRESH = 12000; #endif int nMaxHeightGuess = 1, nCounter = 0, nRefresh = nREFRESH; ::int64_t n64MsStartTime = GetTimeMillis(); #endif // The block index is an in-memory structure that maps hashes to on-disk // locations where the contents of the block can be found. Here, we scan it // out of the DB and into mapBlockIndex. leveldb::Iterator *iterator = pdb->NewIterator(leveldb::ReadOptions()); // Seek to start key. CDataStream ssStartKey(SER_DISK, CLIENT_VERSION); ssStartKey << make_pair(string("blockindex"), uint256(0)); iterator->Seek(ssStartKey.str()); // Now read each entry. while (iterator->Valid()) { // Unpack keys and values. CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.write(iterator->key().data(), iterator->key().size()); CDataStream ssValue(SER_DISK, CLIENT_VERSION); ssValue.write(iterator->value().data(), iterator->value().size()); string strType; ssKey >> strType; // Did we reach the end of the data to read? if (fRequestShutdown || strType != "blockindex") break; CDiskBlockIndex diskindex; ssValue >> diskindex; uint256 blockHash = diskindex.GetBlockHash(); if ( 0 == blockHash ) { if (fPrintToConsole) (void)printf( "Error? at nHeight=%d" "\n" "", diskindex.nHeight ); continue; //? } // Construct block index object CBlockIndex * pindexNew = InsertBlockIndex(blockHash); // what if null? Can't be, since blockhash is known to be != 0 //if( NULL == pindexNew ) // ??? //{ // iterator->Next(); // continue; //} pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); pindexNew->nFile = diskindex.nFile; pindexNew->nBlockPos = diskindex.nBlockPos; pindexNew->nHeight = diskindex.nHeight; pindexNew->nMint = diskindex.nMint; pindexNew->nMoneySupply = diskindex.nMoneySupply; pindexNew->nFlags = diskindex.nFlags; pindexNew->nStakeModifier = diskindex.nStakeModifier; pindexNew->prevoutStake = diskindex.prevoutStake; pindexNew->nStakeTime = diskindex.nStakeTime; pindexNew->hashProofOfStake = diskindex.hashProofOfStake; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; // Watch for genesis block if( (0 == diskindex.nHeight) && (NULL != pindexGenesisBlock) ) { if (fPrintToConsole) (void)printf( "Error? an extra null block???" "\n" "" ); } if ( (0 == diskindex.nHeight) && // ought to be faster than a hash check!? (NULL == pindexGenesisBlock) ) { if (blockHash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet))// check anyway, but only if block 0 { pindexGenesisBlock = pindexNew; /************* #ifdef WIN32 if (fPrintToConsole) (void)printf( "Found block 0 at nCounter=%d" "\n" "", nCounter ); #endif *************/ } else { if (fPrintToConsole) (void)printf( "Error? a extra genesis block with the wrong hash???" "\n" "" ); } } // there seem to be 2 errant blocks? else { if( (NULL != pindexGenesisBlock) && (0 == diskindex.nHeight) ) { if (fPrintToConsole) (void)printf( "Error? a extra genesis null block???" "\n" "" ); } } //if (!pindexNew->CheckIndex()) // as it stands, this never fails??? So why bother????? //{ // delete iterator; // return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); //} // NovaCoin: build setStakeSeen if (pindexNew->IsProofOfStake()) setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); #ifdef WIN32 ++nCounter; // could "guess at the max nHeight & %age against the loop count // to "hone in on" the %age done. // Towards the end it ought to be pretty accurate. if( nMaxHeightGuess < pindexNew->nHeight ) { nMaxHeightGuess = pindexNew->nHeight; } if( 0 == ( nCounter % nRefresh ) ) // every nRefresh-th time through the loop { float // these #s are just to slosh the . around dEstimate = float( ( 100.0 * nCounter ) / nMaxHeightGuess ); std::string sGutsNoise = strprintf( "%7d (%3.2f%%)" "", nCounter, //pindexNew->nHeight, dEstimate > 100.0? 100.0: dEstimate ); if (fPrintToConsole) { /**************** (void)printf( "%s" " " "", sGutsNoise.c_str() ); ****************/ DoProgress( nCounter, nMaxHeightGuess, n64MsStartTime ); //(void)printf( // "\r" // ); } #ifdef QT_GUI // uiInterface.InitMessage( sGutsNoise.c_str() ); #endif } #endif iterator->Next(); } delete iterator; if (fRequestShutdown) return true; #ifdef WIN32 if (fPrintToConsole) (void)printf( "\n" ); #ifdef QT_GUI uiInterface.InitMessage(_("<b>...done.</b>")); #endif #endif // <<<<<<<<< #ifdef WIN32 if (fPrintToConsole) (void)printf( "Sorting by height...\n" ); #ifdef QT_GUI uiInterface.InitMessage( _("Sorting by height...") ); #endif nCounter = 0; #endif // Calculate bnChainTrust { LOCK(cs_main); vector< pair< int, CBlockIndex*> > vSortedByHeight; vSortedByHeight.reserve(mapBlockIndex.size()); //vSortedByHeight.resize( mapBlockIndex.size() ); int nUpdatePeriod = 10000; BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) { CBlockIndex * pindex = item.second; vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); #ifdef WIN32 ++nCounter; if( 0 == (nCounter % nUpdatePeriod) ) { #ifdef QT_GUI uiInterface.InitMessage( strprintf( _("%7d"), nCounter ) ); #else if (fPrintToConsole) printf( "%7d\r", nCounter ); #endif } #endif } sort(vSortedByHeight.begin(), vSortedByHeight.end()); #ifdef WIN32 if (fPrintToConsole) (void)printf( "\ndone\nChecking stake checksums...\n" ); #ifdef _DEBUG nUpdatePeriod /= 4; // speed up update for debug mode #else nUpdatePeriod *= 5; // slow down update for release mode #endif #ifdef QT_GUI uiInterface.InitMessage( _("done") ); uiInterface.InitMessage( _("Checking stake checksums...") ); #endif nCounter = 0; #endif BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) { CBlockIndex* pindex = item.second; pindex->nPosBlockCount = ( pindex->pprev ? pindex->pprev->nPosBlockCount : 0 ) + ( pindex->IsProofOfStake() ? 1 : 0 ); pindex->nBitsMA = pindex->IsProofOfStake() ? GetProofOfWorkMA(pindex->pprev) : 0; pindex->bnChainTrust = (pindex->pprev ? pindex->pprev->bnChainTrust : CBigNum(0)) + pindex->GetBlockTrust(); // NovaCoin: calculate stake modifier checksum pindex->nStakeModifierChecksum = GetStakeModifierChecksum(pindex); if (!CheckStakeModifierCheckpoints(pindex->nHeight, pindex->nStakeModifierChecksum)) return error("CTxDB::LoadBlockIndex() : Failed stake modifier checkpoint height=%d, modifier=0x%016" PRIx64, pindex->nHeight, pindex->nStakeModifier); #ifdef WIN32 ++nCounter; if( 0 == (nCounter % nUpdatePeriod) ) { #ifdef QT_GUI uiInterface.InitMessage( strprintf( _("%7d"), nCounter ) ); #else if (fPrintToConsole) printf( "%7d\r", nCounter ); #endif } #endif } } #ifdef WIN32 if (fPrintToConsole) (void)printf( "\ndone\n" "Read best chain\n" ); #ifdef QT_GUI uiInterface.InitMessage( _("...done") ); uiInterface.InitMessage( _("Read best chain") ); #endif #endif // Load hashBestChain pointer to end of best chain if (!ReadHashBestChain(hashBestChain)) { if (pindexGenesisBlock == NULL) return true; return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded"); } if (!mapBlockIndex.count(hashBestChain)) return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index"); pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; bnBestChainTrust = pindexBest->bnChainTrust; printf("LoadBlockIndex(): hashBestChain=%s height=%d trust=%s date=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); // NovaCoin: load hashSyncCheckpoint if( !fTestNet ) { if (!ReadSyncCheckpoint(Checkpoints::hashSyncCheckpoint)) return error("CTxDB::LoadBlockIndex() : hashSyncCheckpoint not loaded"); printf("LoadBlockIndex(): synchronized checkpoint %s\n", Checkpoints::hashSyncCheckpoint.ToString().c_str() ); } // Load bnBestInvalidTrust, OK if it doesn't exist ReadBestInvalidTrust(bnBestInvalidTrust); // Verify blocks in the best chain int nCheckLevel = GetArg("-checklevel", 1); int nCheckDepth = GetArg( "-checkblocks", 750); if (nCheckDepth == 0) nCheckDepth = 1000000000; // suffices until the year 19000 if (nCheckDepth > nBestHeight) nCheckDepth = nBestHeight; #ifdef WIN32 nCounter = 0; //#ifdef _MSC_VER #ifdef _DEBUG /**************** const int nMINUTESperBLOCK = 1, // or whatever you want to do in this *coin nMINUTESperHOUR = 60, nBLOCKSperHOUR = nMINUTESperHOUR / nMINUTESperBLOCK, nHOURStoCHECK = 1, //12, // this could be a variable nBLOCKSinLASTwhateverHOURS = nBLOCKSperHOUR * nHOURStoCHECK; nCheckDepth = nBLOCKSinLASTwhateverHOURS; ****************/ #endif //#endif #ifdef QT_GUI std::string sX; uiInterface.InitMessage( strprintf( _("Verifying the last %i blocks at level %i"), nCheckDepth, nCheckLevel ).c_str() ); #endif #endif printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); CBlockIndex* pindexFork = NULL; map<pair<unsigned int, unsigned int>, CBlockIndex*> mapBlockPos; for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) { if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; CBlock block; if (!block.ReadFromDisk(pindex)) return error("LoadBlockIndex() : block.ReadFromDisk failed"); // check level 1: verify block validity // check level 7: verify block signature too if (nCheckLevel>0 && !block.CheckBlock(true, true, (nCheckLevel>6))) { printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); pindexFork = pindex->pprev; } // check level 2: verify transaction index validity if (nCheckLevel>1) { pair<unsigned int, unsigned int> pos = make_pair(pindex->nFile, pindex->nBlockPos); mapBlockPos[pos] = pindex; BOOST_FOREACH(const CTransaction &tx, block.vtx) { uint256 hashTx = tx.GetHash(); CTxIndex txindex; if (ReadTxIndex(hashTx, txindex)) { // check level 3: checker transaction hashes if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos) { // either an error or a duplicate transaction CTransaction txFound; if (!txFound.ReadFromDisk(txindex.pos)) { printf("LoadBlockIndex() : *** cannot read mislocated transaction %s\n", hashTx.ToString().c_str()); pindexFork = pindex->pprev; } else if (txFound.GetHash() != hashTx) // not a duplicate tx { printf("LoadBlockIndex(): *** invalid tx position for %s\n", hashTx.ToString().c_str()); pindexFork = pindex->pprev; } } // check level 4: check whether spent txouts were spent within the main chain unsigned int nOutput = 0; if (nCheckLevel>3) { BOOST_FOREACH(const CDiskTxPos &txpos, txindex.vSpent) { if (!txpos.IsNull()) { pair<unsigned int, unsigned int> posFind = make_pair(txpos.nFile, txpos.nBlockPos); if (!mapBlockPos.count(posFind)) { printf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), hashTx.ToString().c_str()); pindexFork = pindex->pprev; } // check level 6: check whether spent txouts were spent by a valid transaction that consume them if (nCheckLevel>5) { CTransaction txSpend; if (!txSpend.ReadFromDisk(txpos)) { printf("LoadBlockIndex(): *** cannot read spending transaction of %s:%i from disk\n", hashTx.ToString().c_str(), nOutput); pindexFork = pindex->pprev; } else if (!txSpend.CheckTransaction()) { printf("LoadBlockIndex(): *** spending transaction of %s:%i is invalid\n", hashTx.ToString().c_str(), nOutput); pindexFork = pindex->pprev; } else { bool fFound = false; BOOST_FOREACH(const CTxIn &txin, txSpend.vin) if (txin.prevout.hash == hashTx && txin.prevout.n == nOutput) fFound = true; if (!fFound) { printf("LoadBlockIndex(): *** spending transaction of %s:%i does not spend it\n", hashTx.ToString().c_str(), nOutput); pindexFork = pindex->pprev; } } } } ++nOutput; } } }