void CTxMemPool::check(const CCoinsViewCache *pcoins) const { LOCK(cs); if (nCheckFrequency == 0) return; if (GetRand(std::numeric_limits<uint32_t>::max()) >= nCheckFrequency) return; LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); uint64_t checkTotal = 0; uint64_t innerUsage = 0; CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins)); const int64_t spendheight = GetSpendHeight(mempoolDuplicate); std::list<const CTxMemPoolEntry*> waitingOnDependants; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { unsigned int i = 0; checkTotal += it->GetTxSize(); innerUsage += it->DynamicMemoryUsage(); const CTransaction& tx = it->GetTx(); txlinksMap::const_iterator linksiter = mapLinks.find(it); assert(linksiter != mapLinks.end()); const TxLinks &links = linksiter->second; innerUsage += memusage::DynamicUsage(links.parents) + memusage::DynamicUsage(links.children); bool fDependsWait = false; setEntries setParentCheck; int64_t parentSizes = 0; int64_t parentSigOpCost = 0; for (const CTxIn &txin : tx.vin) { // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); if (it2 != mapTx.end()) { const CTransaction& tx2 = it2->GetTx(); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); fDependsWait = true; if (setParentCheck.insert(it2).second) { parentSizes += it2->GetTxSize(); parentSigOpCost += it2->GetSigOpCost(); } } else { assert(pcoins->HaveCoin(txin.prevout)); } // Check whether its inputs are marked in mapNextTx. auto it3 = mapNextTx.find(txin.prevout); assert(it3 != mapNextTx.end()); assert(it3->first == &txin.prevout); assert(it3->second == &tx); i++; } assert(setParentCheck == GetMemPoolParents(it)); // Verify ancestor state is correct. setEntries setAncestors; uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); std::string dummy; CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy); uint64_t nCountCheck = setAncestors.size() + 1; uint64_t nSizeCheck = it->GetTxSize(); CAmount nFeesCheck = it->GetModifiedFee(); int64_t nSigOpCheck = it->GetSigOpCost(); for (txiter ancestorIt : setAncestors) { nSizeCheck += ancestorIt->GetTxSize(); nFeesCheck += ancestorIt->GetModifiedFee(); nSigOpCheck += ancestorIt->GetSigOpCost(); } assert(it->GetCountWithAncestors() == nCountCheck); assert(it->GetSizeWithAncestors() == nSizeCheck); assert(it->GetSigOpCostWithAncestors() == nSigOpCheck); assert(it->GetModFeesWithAncestors() == nFeesCheck); // Check children against mapNextTx CTxMemPool::setEntries setChildrenCheck; auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); int64_t childSizes = 0; for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) { txiter childit = mapTx.find(iter->second->GetHash()); assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions if (setChildrenCheck.insert(childit).second) { childSizes += childit->GetTxSize(); } } assert(setChildrenCheck == GetMemPoolChildren(it)); // Also check to make sure size is greater than sum with immediate children. // just a sanity check, not definitive that this calc is correct... assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); if (fDependsWait) waitingOnDependants.push_back(&(*it)); else { CheckInputsAndUpdateCoins(tx, mempoolDuplicate, spendheight); } } unsigned int stepsSinceLastRemove = 0; while (!waitingOnDependants.empty()) { const CTxMemPoolEntry* entry = waitingOnDependants.front(); waitingOnDependants.pop_front(); CValidationState state; if (!mempoolDuplicate.HaveInputs(entry->GetTx())) { waitingOnDependants.push_back(entry); stepsSinceLastRemove++; assert(stepsSinceLastRemove < waitingOnDependants.size()); } else { CheckInputsAndUpdateCoins(entry->GetTx(), mempoolDuplicate, spendheight); stepsSinceLastRemove = 0; } } for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) { uint256 hash = it->second->GetHash(); indexed_transaction_set::const_iterator it2 = mapTx.find(hash); const CTransaction& tx = it2->GetTx(); assert(it2 != mapTx.end()); assert(&tx == it->second); } assert(totalTxSize == checkTotal); assert(innerUsage == cachedInnerUsage); }
// returns -1 on error conditions double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal, double successBreakPoint, bool requireGreater, unsigned int nBlockHeight, EstimationResult *result) const { // Counters for a bucket (or range of buckets) double nConf = 0; // Number of tx's confirmed within the confTarget double totalNum = 0; // Total number of tx's that were ever confirmed int extraNum = 0; // Number of tx's still in mempool for confTarget or longer double failNum = 0; // Number of tx's that were never confirmed but removed from the mempool after confTarget int periodTarget = (confTarget + scale - 1)/scale; int maxbucketindex = buckets.size() - 1; // requireGreater means we are looking for the lowest feerate such that all higher // values pass, so we start at maxbucketindex (highest feerate) and look at successively // smaller buckets until we reach failure. Otherwise, we are looking for the highest // feerate such that all lower values fail, and we go in the opposite direction. unsigned int startbucket = requireGreater ? maxbucketindex : 0; int step = requireGreater ? -1 : 1; // We'll combine buckets until we have enough samples. // The near and far variables will define the range we've combined // The best variables are the last range we saw which still had a high // enough confirmation rate to count as success. // The cur variables are the current range we're counting. unsigned int curNearBucket = startbucket; unsigned int bestNearBucket = startbucket; unsigned int curFarBucket = startbucket; unsigned int bestFarBucket = startbucket; bool foundAnswer = false; unsigned int bins = unconfTxs.size(); bool newBucketRange = true; bool passing = true; EstimatorBucket passBucket; EstimatorBucket failBucket; // Start counting from highest(default) or lowest feerate transactions for (int bucket = startbucket; bucket >= 0 && bucket <= maxbucketindex; bucket += step) { if (newBucketRange) { curNearBucket = bucket; newBucketRange = false; } curFarBucket = bucket; nConf += confAvg[periodTarget - 1][bucket]; totalNum += txCtAvg[bucket]; failNum += failAvg[periodTarget - 1][bucket]; for (unsigned int confct = confTarget; confct < GetMaxConfirms(); confct++) extraNum += unconfTxs[(nBlockHeight - confct)%bins][bucket]; extraNum += oldUnconfTxs[bucket]; // If we have enough transaction data points in this range of buckets, // we can test for success // (Only count the confirmed data points, so that each confirmation count // will be looking at the same amount of data and same bucket breaks) if (totalNum >= sufficientTxVal / (1 - decay)) { double curPct = nConf / (totalNum + failNum + extraNum); // Check to see if we are no longer getting confirmed at the success rate if ((requireGreater && curPct < successBreakPoint) || (!requireGreater && curPct > successBreakPoint)) { if (passing == true) { // First time we hit a failure record the failed bucket unsigned int failMinBucket = std::min(curNearBucket, curFarBucket); unsigned int failMaxBucket = std::max(curNearBucket, curFarBucket); failBucket.start = failMinBucket ? buckets[failMinBucket - 1] : 0; failBucket.end = buckets[failMaxBucket]; failBucket.withinTarget = nConf; failBucket.totalConfirmed = totalNum; failBucket.inMempool = extraNum; failBucket.leftMempool = failNum; passing = false; } continue; } // Otherwise update the cumulative stats, and the bucket variables // and reset the counters else { failBucket = EstimatorBucket(); // Reset any failed bucket, currently passing foundAnswer = true; passing = true; passBucket.withinTarget = nConf; nConf = 0; passBucket.totalConfirmed = totalNum; totalNum = 0; passBucket.inMempool = extraNum; passBucket.leftMempool = failNum; failNum = 0; extraNum = 0; bestNearBucket = curNearBucket; bestFarBucket = curFarBucket; newBucketRange = true; } } } double median = -1; double txSum = 0; // Calculate the "average" feerate of the best bucket range that met success conditions // Find the bucket with the median transaction and then report the average feerate from that bucket // This is a compromise between finding the median which we can't since we don't save all tx's // and reporting the average which is less accurate unsigned int minBucket = std::min(bestNearBucket, bestFarBucket); unsigned int maxBucket = std::max(bestNearBucket, bestFarBucket); for (unsigned int j = minBucket; j <= maxBucket; j++) { txSum += txCtAvg[j]; } if (foundAnswer && txSum != 0) { txSum = txSum / 2; for (unsigned int j = minBucket; j <= maxBucket; j++) { if (txCtAvg[j] < txSum) txSum -= txCtAvg[j]; else { // we're in the right bucket median = avg[j] / txCtAvg[j]; break; } } passBucket.start = minBucket ? buckets[minBucket-1] : 0; passBucket.end = buckets[maxBucket]; } // If we were passing until we reached last few buckets with insufficient data, then report those as failed if (passing && !newBucketRange) { unsigned int failMinBucket = std::min(curNearBucket, curFarBucket); unsigned int failMaxBucket = std::max(curNearBucket, curFarBucket); failBucket.start = failMinBucket ? buckets[failMinBucket - 1] : 0; failBucket.end = buckets[failMaxBucket]; failBucket.withinTarget = nConf; failBucket.totalConfirmed = totalNum; failBucket.inMempool = extraNum; failBucket.leftMempool = failNum; } LogPrint(BCLog::ESTIMATEFEE, "FeeEst: %d %s%.0f%% decay %.5f: feerate: %g from (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n", confTarget, requireGreater ? ">" : "<", 100.0 * successBreakPoint, decay, median, passBucket.start, passBucket.end, 100 * passBucket.withinTarget / (passBucket.totalConfirmed + passBucket.inMempool + passBucket.leftMempool), passBucket.withinTarget, passBucket.totalConfirmed, passBucket.inMempool, passBucket.leftMempool, failBucket.start, failBucket.end, 100 * failBucket.withinTarget / (failBucket.totalConfirmed + failBucket.inMempool + failBucket.leftMempool), failBucket.withinTarget, failBucket.totalConfirmed, failBucket.inMempool, failBucket.leftMempool); if (result) { result->pass = passBucket; result->fail = failBucket; result->decay = decay; result->scale = scale; } return median; }
void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg) { Q_UNUSED(context); const char *category = (type == QtDebugMsg) ? "qt" : NULL; LogPrint(category, "GUI: %s\n", msg.toStdString()); }
void InterruptHTTPRPC() { LogPrint(BCLog::RPC, "Interrupting HTTP RPC server\n"); }
bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS) { // we are a masternode with the same vin (i.e. already activated) and this mnb is ours (matches our Masternode privkey) // so nothing to do here for us if(fMasterNode && vin.prevout == activeMasternode.vin.prevout && pubkey2 == activeMasternode.pubKeyMasternode) return true; // search existing Masternode list CMasternode* pmn = mnodeman.Find(vin); if(pmn != NULL) { // nothing to do here if we already know about this masternode and it's enabled if(pmn->IsEnabled()) return true; // if it's not enabled, remove old MN first and continue else mnodeman.Remove(pmn->vin); } CValidationState state; CMutableTransaction tx = CMutableTransaction(); CTxOut vout = CTxOut(9999.99*COIN, obfuScationPool.collateralPubKey); tx.vin.push_back(vin); tx.vout.push_back(vout); { TRY_LOCK(cs_main, lockMain); if(!lockMain) { // not mnb fault, let it to be checked again later mnodeman.mapSeenMasternodeBroadcast.erase(GetHash()); masternodeSync.mapSeenSyncMNB.erase(GetHash()); return false; } if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)) { //set nDos state.IsInvalid(nDoS); return false; } } LogPrint("masternode", "mnb - Accepted Masternode entry\n"); if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ LogPrintf("mnb - Input must have at least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS); // maybe we miss few blocks, let this mnb to be checked again later mnodeman.mapSeenMasternodeBroadcast.erase(GetHash()); masternodeSync.mapSeenSyncMNB.erase(GetHash()); return false; } // verify that sig time is legit in past // should be at least not earlier than block when 1000 DNET tx got MASTERNODE_MIN_CONFIRMATIONS uint256 hashBlock = 0; CTransaction tx2; GetTransaction(vin.prevout.hash, tx2, hashBlock, true); BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DNET tx -> 1 confirmation CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS if(pConfIndex->GetBlockTime() > sigTime) { LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n", sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime()); return false; } } LogPrintf("mnb - Got NEW Masternode entry - %s - %s - %s - %lli \n", GetHash().ToString(), addr.ToString(), vin.ToString(), sigTime); CMasternode mn(*this); mnodeman.Add(mn); // if it matches our Masternode privkey, then we've been remotely activated if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){ activeMasternode.EnableHotColdMasterNode(vin, addr); } bool isLocal = addr.IsRFC1918() || addr.IsLocal(); if(Params().NetworkID() == CBaseChainParams::REGTEST) isLocal = false; if(!isLocal) Relay(); return true; }
bool ModelMilkshape::LoadModelData( std::string filename ) { LogPrint("Loading Milkshape3D Model %s.",filename.c_str()); this->modelname = filename; std::ifstream inputFile( filename.c_str(), std::ios::in | std::ios::binary /*| ios::nocreate*/ ); if ( !inputFile ) { LogPrint("Error Loading Milkshape3D Model: File Not Found %s.", filename.c_str()); return false; // "Couldn't open the model file." } inputFile.seekg( 0, std::ios::end ); long fileSize = inputFile.tellg(); inputFile.seekg( 0, std::ios::beg ); LogPrint("Allocating %d For Model Data", fileSize); byte *pBuffer = new byte[fileSize]; inputFile.read( (char *)pBuffer, fileSize ); inputFile.close(); const byte *pPtr = pBuffer; MS3DHeader *pHeader = ( MS3DHeader* )pPtr; pPtr += sizeof( MS3DHeader ); LogPrint("HeaderID: %s", pHeader->m_ID); LogPrint("Version: %d", pHeader->m_version); if ( strncmp( pHeader->m_ID, "MS3D000000", 10 ) != 0 ) { LogPrint("Error Loading Milkshape3D Model: Not a valid Milkshape3D model file."); return false; // "Not a valid Milkshape3D model file." } if ( pHeader->m_version < 3 || pHeader->m_version > 4 ) { LogPrint("Error Loading Milkshape3D Model: Unhandled file version. Only Milkshape3D Version 1.3 and 1.4 are supported."); return false; } int nVertices = *( word* )pPtr; this->numVertices = nVertices; this->vertices = new Model::Vertex[nVertices]; pPtr += sizeof( word ); int i; for ( i = 0; i < nVertices; i++ ) { MS3DVertex *pVertex = ( MS3DVertex* )pPtr; this->vertices[i].boneID = pVertex->m_boneID; memcpy( this->vertices[i].location, pVertex->m_vertex, sizeof( float )*3 ); pPtr += sizeof( MS3DVertex ); } int nTriangles = *( word* )pPtr; this->numTriangles = nTriangles; this->triangles = new Model::Triangle[nTriangles]; pPtr += sizeof( word ); for ( i = 0; i < nTriangles; i++ ) { MS3DTriangle *pTriangle = ( MS3DTriangle* )pPtr; int vertexIndices[3] = { pTriangle->m_vertexIndices[0], pTriangle->m_vertexIndices[1], pTriangle->m_vertexIndices[2] }; float texCoordT_fixed[3] = { 1.0f-pTriangle->m_t[0], 1.0f-pTriangle->m_t[1], 1.0f-pTriangle->m_t[2] }; memcpy( this->triangles[i].vertexNormals, pTriangle->m_vertexNormals, sizeof( float )*3*3 ); memcpy( this->triangles[i].texCoordS, pTriangle->m_s, sizeof( float )*3 ); memcpy( this->triangles[i].texCoordT, texCoordT_fixed, sizeof( float )*3 ); memcpy( this->triangles[i].vertexIndices, vertexIndices, sizeof( int )*3 ); pPtr += sizeof( MS3DTriangle ); } int nGroups = *( word* )pPtr; this->numMeshes = nGroups; this->meshes = new Model::Mesh[nGroups]; pPtr += sizeof( word ); for ( i = 0; i < nGroups; i++ ) { pPtr += sizeof( byte ); // flags pPtr += 32; // name word nTriangles = *( word* )pPtr; pPtr += sizeof( word ); int *pTriangleIndices = new int[nTriangles]; for ( int j = 0; j < nTriangles; j++ ) { pTriangleIndices[j] = *( word* )pPtr; pPtr += sizeof( word ); } char materialIndex = *( char* )pPtr; pPtr += sizeof( char ); this->meshes[i].materialIndex = materialIndex; this->meshes[i].numTriangles = nTriangles; this->meshes[i].triangleIndices = pTriangleIndices; } int nMaterials = *( word* )pPtr; this->numMaterials = nMaterials; this->materials = new Model::Material[nMaterials]; pPtr += sizeof( word ); for ( i = 0; i < nMaterials; i++ ) { MS3DMaterial *pMaterial = ( MS3DMaterial* )pPtr; memcpy( this->materials[i].ambient, pMaterial->m_ambient, sizeof( float )*4 ); memcpy( this->materials[i].diffuse, pMaterial->m_diffuse, sizeof( float )*4 ); memcpy( this->materials[i].specular, pMaterial->m_specular, sizeof( float )*4 ); memcpy( this->materials[i].emissive, pMaterial->m_emissive, sizeof( float )*4 ); this->materials[i].shininess = pMaterial->m_shininess; this->materials[i].textureFilename = new char[strlen( pMaterial->m_texture ) + 1]; strcpy( this->materials[i].textureFilename, pMaterial->m_texture ); pPtr += sizeof( MS3DMaterial ); } delete[] pBuffer; this->calculateRadius(); LogPrint("\tFound : %d Vertex.", this->numVertices); LogPrint("\tFound : %d Triangle.", this->numTriangles); LogPrint("\tFound : %d Material.", this->numMaterials); LogPrint("\tFound : %d Meshes.", this->numMeshes); // load the shaders this->InitShaders( filename); this->loaded = true; LogPrint("Model Loaded Successfully"); return true; }
int CProgStatusBar::ShowProgressCtrl(){ CPostMsg postmsg; if (!theApp.m_msgProcessBarQueue.pop(postmsg)) { return 1; } uistruct::BLOCKCHANGED_t pBlockchanged; string strTemp = postmsg.GetData(); pBlockchanged.JsonToStruct(strTemp.c_str()); LogPrint("CProgStatusBar", "MSG_USER_UP_PROGRESS WM_CONNECTNET 更新进度条消息:%s\n",strTemp.c_str()); if (pBlockchanged.tips <= 0) { return 1; } //// blocktip高度 theApp.m_nBlockTipHight = pBlockchanged.tips ; if (!m_bProgressType) { string strTemp = ""; strTemp = strprintf("%s%s",m_strNetName , "网络同步中..."); m_strNeting.SetWindowText(strTemp.c_str()); m_strNeting.ShowWindow(SW_HIDE); m_strNeting.ShowWindow(SW_SHOW); m_progress.SetRange32( 0 , 100); int setpos =(int)((pBlockchanged.high*1.0/pBlockchanged.tips)*100) ; setpos = setpos>100?100:setpos; //设置进度条的值 m_progress.SetPos(setpos); CString strText; strText.AppendFormat("%s ~%d", "剩余", pBlockchanged.tips-pBlockchanged.high); strText.AppendFormat(" %s","块没有同步到本地"); m_progress.SetDefinedStr(strText); m_bProgressType = TRUE; m_nSigIndex =pBlockchanged.connections>3?3:pBlockchanged.connections; m_nConnectCount = pBlockchanged.connections; if (pBlockchanged.tips==pBlockchanged.high) { //theApp.IsSyncAppTx = TRUE; /// 同步app交易 } if ((pBlockchanged.tips-pBlockchanged.high)<10 && !m_bIsWalletUI) { TRACE("ok:%s\r\n","OnShowProgressCtrl"); //// 发送钱包同步完毕 CPostMsg postblockmsg(MSG_USER_MAIN_UI,WM_UPWALLET); theApp.m_msgQueue.pushFront(postblockmsg); LoadGifing(false); m_bIsWalletUI = true; theApp.m_bIsSyncBlock = true; } Invalidate(); //InvalidateRect(m_bmpsig); // return 1; } m_nSigIndex = pBlockchanged.connections>3?3:pBlockchanged.connections; int setpos =(int) ((pBlockchanged.high*1.0/pBlockchanged.tips)*100) ; setpos = setpos>100?100:setpos; //设置进度条的值 m_progress.SetPos(setpos); CString strText; strText.AppendFormat("%s ~%d", "剩余", pBlockchanged.tips-pBlockchanged.high); strText.AppendFormat(" %s","块没有同步到本地"); m_progress.SetDefinedStr(strText); m_progress.Invalidate(); if (pBlockchanged.tips==pBlockchanged.high) { //theApp.IsSyncAppTx = TRUE; /// 同步app交易 } if ((pBlockchanged.tips-pBlockchanged.high)<10&& !m_bIsWalletUI) { TRACE("ok:%s\r\n","OnShowProgressCtrl"); //// 发送钱包同步完毕 CPostMsg postblockmsg(MSG_USER_MAIN_UI,WM_UPWALLET); theApp.m_msgQueue.pushFront(postblockmsg); LoadGifing(false); m_bIsWalletUI = true; theApp.m_bIsSyncBlock = true; } if ( m_bIsWalletUI && !m_bIsShowProgress) { string strTemp = ""; strTemp =strprintf("%s%s",m_strNetName , "网络同步中..."); m_strNeting.SetWindowText(strTemp.c_str()) ; m_strNeting.ShowWindow(SW_HIDE); m_strNeting.ShowWindow(SW_SHOW); m_progress.ShowWindow(SW_HIDE); if ( NULL != m_ProgressWnd ) { m_ProgressWnd->ShowWindow(SW_HIDE) ; } if (m_bIsShowProgress == false) { m_bIsShowProgress =true; }else{ m_bIsShowProgress =false; } } if (m_bIsWalletUI && m_bIsShowProgress) { string strTemp; strTemp = strprintf("%s网络",m_strNetName); m_strNeting.SetWindowText(strTemp.c_str()); m_strNeting.ShowWindow(SW_HIDE); m_strNeting.ShowWindow(SW_SHOW); string strTips; strTips = strprintf("%s:%d" ,"当前高度" ,pBlockchanged.tips ); m_strHeight.SetWindowText(strTips.c_str()) ; m_strHeight.ShowWindow(SW_HIDE); m_strHeight.ShowWindow(SW_SHOW); CRect rc; m_strNeting.GetWindowRect(&rc); m_strNeting.MoveWindow(30 , 12, 58, rc.Height()); } InvalidateRect(m_rectSignal); SetAppStepfee(pBlockchanged.fuelrate); return 1; }
void InterruptHTTPRPC() { LogPrint("rpc", "Interrupting HTTP RPC server\n"); }
void NTCPClient::Connect () { LogPrint ("Connecting to ", m_Endpoint.address ().to_string (),":", m_Endpoint.port ()); GetSocket ().async_connect (m_Endpoint, boost::bind (&NTCPClient::HandleConnect, this, boost::asio::placeholders::error)); }
void TxConfirmStats::Read(CAutoFile& filein) { // Read data file into temporary variables and do some very basic sanity checking std::vector<double> fileBuckets; std::vector<double> fileAvg; std::vector<std::vector<double> > fileConfAvg; std::vector<double> fileTxCtAvg; double fileDecay; size_t maxConfirms; size_t numBuckets; filein >> fileDecay; if (fileDecay <= 0 || fileDecay >= 1) throw std::runtime_error("Corrupt estimates file. Decay must be between 0 and 1 (non-inclusive)"); filein >> fileBuckets; numBuckets = fileBuckets.size(); if (numBuckets <= 1 || numBuckets > 1000) throw std::runtime_error("Corrupt estimates file. Must have between 2 and 1000 fee/pri buckets"); filein >> fileAvg; if (fileAvg.size() != numBuckets) throw std::runtime_error("Corrupt estimates file. Mismatch in fee/pri average bucket count"); filein >> fileTxCtAvg; if (fileTxCtAvg.size() != numBuckets) throw std::runtime_error("Corrupt estimates file. Mismatch in tx count bucket count"); filein >> fileConfAvg; maxConfirms = fileConfAvg.size(); if (maxConfirms <= 0 || maxConfirms > 6 * 24 * 7) // one week throw std::runtime_error("Corrupt estimates file. Must maintain estimates for between 1 and 1008 (one week) confirms"); for (unsigned int i = 0; i < maxConfirms; i++) { if (fileConfAvg[i].size() != numBuckets) throw std::runtime_error("Corrupt estimates file. Mismatch in fee/pri conf average bucket count"); } // Now that we've processed the entire fee estimate data file and not // thrown any errors, we can copy it to our data structures decay = fileDecay; buckets = fileBuckets; avg = fileAvg; confAvg = fileConfAvg; txCtAvg = fileTxCtAvg; bucketMap.clear(); // Resize the current block variables which aren't stored in the data file // to match the number of confirms and buckets curBlockConf.resize(maxConfirms); for (unsigned int i = 0; i < maxConfirms; i++) { curBlockConf[i].resize(buckets.size()); } curBlockTxCt.resize(buckets.size()); curBlockVal.resize(buckets.size()); unconfTxs.resize(maxConfirms); for (unsigned int i = 0; i < maxConfirms; i++) { unconfTxs[i].resize(buckets.size()); } oldUnconfTxs.resize(buckets.size()); for (unsigned int i = 0; i < buckets.size(); i++) bucketMap[buckets[i]] = i; LogPrint("estimatefee", "Reading estimates: %u %s buckets counting confirms up to %u blocks\n", numBuckets, dataTypeString, maxConfirms); }
// returns -1 on error conditions double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal, double successBreakPoint, bool requireGreater, unsigned int nBlockHeight) { // Counters for a bucket (or range of buckets) double nConf = 0; // Number of tx's confirmed within the confTarget double totalNum = 0; // Total number of tx's that were ever confirmed int extraNum = 0; // Number of tx's still in mempool for confTarget or longer int maxbucketindex = buckets.size() - 1; // requireGreater means we are looking for the lowest fee/priority such that all higher // values pass, so we start at maxbucketindex (highest fee) and look at succesively // smaller buckets until we reach failure. Otherwise, we are looking for the highest // fee/priority such that all lower values fail, and we go in the opposite direction. unsigned int startbucket = requireGreater ? maxbucketindex : 0; int step = requireGreater ? -1 : 1; // We'll combine buckets until we have enough samples. // The near and far variables will define the range we've combined // The best variables are the last range we saw which still had a high // enough confirmation rate to count as success. // The cur variables are the current range we're counting. unsigned int curNearBucket = startbucket; unsigned int bestNearBucket = startbucket; unsigned int curFarBucket = startbucket; unsigned int bestFarBucket = startbucket; bool foundAnswer = false; unsigned int bins = unconfTxs.size(); // Start counting from highest(default) or lowest fee/pri transactions for (int bucket = startbucket; bucket >= 0 && bucket <= maxbucketindex; bucket += step) { curFarBucket = bucket; nConf += confAvg[confTarget - 1][bucket]; totalNum += txCtAvg[bucket]; for (unsigned int confct = confTarget; confct < GetMaxConfirms(); confct++) extraNum += unconfTxs[(nBlockHeight - confct)%bins][bucket]; extraNum += oldUnconfTxs[bucket]; // If we have enough transaction data points in this range of buckets, // we can test for success // (Only count the confirmed data points, so that each confirmation count // will be looking at the same amount of data and same bucket breaks) if (totalNum >= sufficientTxVal / (1 - decay)) { double curPct = nConf / (totalNum + extraNum); // Check to see if we are no longer getting confirmed at the success rate if (requireGreater && curPct < successBreakPoint) break; if (!requireGreater && curPct > successBreakPoint) break; // Otherwise update the cumulative stats, and the bucket variables // and reset the counters else { foundAnswer = true; nConf = 0; totalNum = 0; extraNum = 0; bestNearBucket = curNearBucket; bestFarBucket = curFarBucket; curNearBucket = bucket + step; } } } double median = -1; double txSum = 0; // Calculate the "average" fee of the best bucket range that met success conditions // Find the bucket with the median transaction and then report the average fee from that bucket // This is a compromise between finding the median which we can't since we don't save all tx's // and reporting the average which is less accurate unsigned int minBucket = bestNearBucket < bestFarBucket ? bestNearBucket : bestFarBucket; unsigned int maxBucket = bestNearBucket > bestFarBucket ? bestNearBucket : bestFarBucket; for (unsigned int j = minBucket; j <= maxBucket; j++) { txSum += txCtAvg[j]; } if (foundAnswer && txSum != 0) { txSum = txSum / 2; for (unsigned int j = minBucket; j <= maxBucket; j++) { if (txCtAvg[j] < txSum) txSum -= txCtAvg[j]; else { // we're in the right bucket median = avg[j] / txCtAvg[j]; break; } } } LogPrint("estimatefee", "%3d: For conf success %s %4.2f need %s %s: %12.5g from buckets %8g - %8g Cur Bucket stats %6.2f%% %8.1f/(%.1f+%d mempool)\n", confTarget, requireGreater ? ">" : "<", successBreakPoint, dataTypeString, requireGreater ? ">" : "<", median, buckets[minBucket], buckets[maxBucket], 100 * nConf / (totalNum + extraNum), nConf, totalNum, extraNum); return median; }
I2NPMessage * CreateDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID, bool exploratory, std::set<i2p::data::IdentHash> * excludedPeers, bool encryption, i2p::tunnel::TunnelPool * pool) { I2NPMessage * m = NewI2NPMessage (); uint8_t * buf = m->GetPayload (); memcpy (buf, key, 32); // key buf += 32; memcpy (buf, from, 32); // from buf += 32; if (replyTunnelID) { *buf = encryption ? 0x03: 0x01; // set delivery flag *(uint32_t *)(buf+1) = htobe32 (replyTunnelID); buf += 5; } else { encryption = false; // encryption can we set for tunnels only *buf = 0; // flag buf++; } if (exploratory) { *(uint16_t *)buf = htobe16 (1); // one exlude record buf += 2; // reply with non-floodfill routers only memset (buf, 0, 32); buf += 32; } else { if (excludedPeers) { int cnt = excludedPeers->size (); *(uint16_t *)buf = htobe16 (cnt); buf += 2; for (auto& it: *excludedPeers) { memcpy (buf, it, 32); buf += 32; } } else { // nothing to exclude *(uint16_t *)buf = htobe16 (0); buf += 2; } } if (encryption) { // session key and tag for reply auto& rnd = i2p::context.GetRandomNumberGenerator (); rnd.GenerateBlock (buf, 32); // key buf[32] = 1; // 1 tag rnd.GenerateBlock (buf + 33, 32); // tag if (pool) pool->GetLocalDestination ().SubmitSessionKey (buf, buf + 33); // introduce new key-tag to garlic engine else LogPrint ("Destination for encrypteed reply not specified"); buf += 65; } m->len += (buf - m->GetPayload ()); FillI2NPMessageHeader (m, eI2NPDatabaseLookup); return m; }
bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& groups, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet) { setCoinsRet.clear(); nValueRet = 0; // List of values less than target boost::optional<OutputGroup> lowest_larger; std::vector<OutputGroup> applicable_groups; CAmount nTotalLower = 0; random_shuffle(groups.begin(), groups.end(), GetRandInt); for (const OutputGroup& group : groups) { if (group.m_value == nTargetValue) { util::insert(setCoinsRet, group.m_outputs); nValueRet += group.m_value; return true; } else if (group.m_value < nTargetValue + MIN_CHANGE) { applicable_groups.push_back(group); nTotalLower += group.m_value; } else if (!lowest_larger || group.m_value < lowest_larger->m_value) { lowest_larger = group; } } if (nTotalLower == nTargetValue) { for (const auto& group : applicable_groups) { util::insert(setCoinsRet, group.m_outputs); nValueRet += group.m_value; } return true; } if (nTotalLower < nTargetValue) { if (!lowest_larger) return false; util::insert(setCoinsRet, lowest_larger->m_outputs); nValueRet += lowest_larger->m_value; return true; } // Solve subset sum by stochastic approximation std::sort(applicable_groups.begin(), applicable_groups.end(), descending); std::vector<char> vfBest; CAmount nBest; ApproximateBestSubset(applicable_groups, nTotalLower, nTargetValue, vfBest, nBest); if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE) { ApproximateBestSubset(applicable_groups, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest); } // If we have a bigger coin and (either the stochastic approximation didn't find a good solution, // or the next bigger coin is closer), return the bigger coin if (lowest_larger && ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || lowest_larger->m_value <= nBest)) { util::insert(setCoinsRet, lowest_larger->m_outputs); nValueRet += lowest_larger->m_value; } else { for (unsigned int i = 0; i < applicable_groups.size(); i++) { if (vfBest[i]) { util::insert(setCoinsRet, applicable_groups[i].m_outputs); nValueRet += applicable_groups[i].m_value; } } if (LogAcceptCategory(BCLog::SELECTCOINS)) { LogPrint(BCLog::SELECTCOINS, "SelectCoins() best subset: "); /* Continued */ for (unsigned int i = 0; i < applicable_groups.size(); i++) { if (vfBest[i]) { LogPrint(BCLog::SELECTCOINS, "%s ", FormatMoney(applicable_groups[i].m_value)); /* Continued */ } } LogPrint(BCLog::SELECTCOINS, "total %s\n", FormatMoney(nBest)); } } return true; }
bool CGovernanceObject::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, CGovernanceException& exception, CConnman& connman) { if(!mnodeman.Has(vote.GetMasternodeOutpoint())) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Masternode index not found"; exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_WARNING); if(mapOrphanVotes.Insert(vote.GetMasternodeOutpoint(), vote_time_pair_t(vote, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME))) { if(pfrom) { mnodeman.AskForMN(pfrom, vote.GetMasternodeOutpoint(), connman); } LogPrintf("%s\n", ostr.str()); } else { LogPrint("gobject", "%s\n", ostr.str()); } return false; } vote_m_it it = mapCurrentMNVotes.find(vote.GetMasternodeOutpoint()); if(it == mapCurrentMNVotes.end()) { it = mapCurrentMNVotes.insert(vote_m_t::value_type(vote.GetMasternodeOutpoint(), vote_rec_t())).first; } vote_rec_t& recVote = it->second; vote_signal_enum_t eSignal = vote.GetSignal(); if(eSignal == VOTE_SIGNAL_NONE) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Vote signal: none"; LogPrint("gobject", "%s\n", ostr.str()); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_WARNING); return false; } if(eSignal > MAX_SUPPORTED_VOTE_SIGNAL) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Unsupported vote signal: " << CGovernanceVoting::ConvertSignalToString(vote.GetSignal()); LogPrintf("%s\n", ostr.str()); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20); return false; } vote_instance_m_it it2 = recVote.mapInstances.find(int(eSignal)); if(it2 == recVote.mapInstances.end()) { it2 = recVote.mapInstances.insert(vote_instance_m_t::value_type(int(eSignal), vote_instance_t())).first; } vote_instance_t& voteInstance = it2->second; // Reject obsolete votes if(vote.GetTimestamp() < voteInstance.nCreationTime) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Obsolete vote"; LogPrint("gobject", "%s\n", ostr.str()); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_NONE); return false; } int64_t nNow = GetAdjustedTime(); int64_t nVoteTimeUpdate = voteInstance.nTime; if(governance.AreRateChecksEnabled()) { int64_t nTimeDelta = nNow - voteInstance.nTime; if(nTimeDelta < GOVERNANCE_UPDATE_MIN) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Masternode voting too often" << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() << ", governance object hash = " << GetHash().ToString() << ", time delta = " << nTimeDelta; LogPrint("gobject", "%s\n", ostr.str()); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_TEMPORARY_ERROR); nVoteTimeUpdate = nNow; return false; } } // Finally check that the vote is actually valid (done last because of cost of signature verification) if(!vote.IsValid(true)) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Invalid vote" << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() << ", governance object hash = " << GetHash().ToString() << ", vote hash = " << vote.GetHash().ToString(); LogPrintf("%s\n", ostr.str()); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20); governance.AddInvalidVote(vote); return false; } if(!mnodeman.AddGovernanceVote(vote.GetMasternodeOutpoint(), vote.GetParentHash())) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Unable to add governance vote" << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() << ", governance object hash = " << GetHash().ToString(); LogPrint("gobject", "%s\n", ostr.str()); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR); return false; } voteInstance = vote_instance_t(vote.GetOutcome(), nVoteTimeUpdate, vote.GetTimestamp()); if(!fileVotes.HasVote(vote.GetHash())) { fileVotes.AddVote(vote); } fDirtyCache = true; return true; }
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx) { int64_t nTimeStart = GetTimeMicros(); resetBlock(); pblocktemplate.reset(new CBlockTemplate()); if(!pblocktemplate.get()) return nullptr; pblock = &pblocktemplate->block; // pointer for convenience // Add dummy coinbase tx as first transaction pblock->vtx.emplace_back(); pblocktemplate->vTxFees.push_back(-1); // updated at end pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end LOCK2(cs_main, mempool.cs); CBlockIndex* pindexPrev = chainActive.Tip(); nHeight = pindexPrev->nHeight + 1; pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()); // -regtest only: allow overriding block.nVersion with // -blockversion=N to test forking scenarios if (chainparams.MineBlocksOnDemand()) pblock->nVersion = GetArg("-blockversion", pblock->nVersion); pblock->nTime = GetAdjustedTime(); const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) ? nMedianTimePast : pblock->GetBlockTime(); // Decide whether to include witness transactions // This is only needed in case the witness softfork activation is reverted // (which would require a very deep reorganization) or when // -promiscuousmempoolflags is used. // TODO: replace this with a call to main to assess validity of a mempool // transaction (which in most cases can be a no-op). fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx; int nPackagesSelected = 0; int nDescendantsUpdated = 0; addPackageTxs(nPackagesSelected, nDescendantsUpdated); int64_t nTime1 = GetTimeMicros(); nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; nLastBlockWeight = nBlockWeight; // Create coinbase transaction. CMutableTransaction coinbaseTx; coinbaseTx.vin.resize(1); coinbaseTx.vin[0].prevout.SetNull(); coinbaseTx.vout.resize(1); coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn; coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx)); pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus()); pblocktemplate->vTxFees[0] = -nFees; uint64_t nSerializeSize = GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION); LogPrintf("CreateNewBlock(): total size: %u block weight: %u txs: %u fees: %ld sigops %d\n", nSerializeSize, GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost); // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); pblock->nNonce = 0; pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]); CValidationState state; if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state))); } int64_t nTime2 = GetTimeMicros(); LogPrint(BCLog::BENCH, "CreateNewBlock() packages: %.2fms (%d packages, %d updated descendants), validity: %.2fms (total %.2fms)\n", 0.001 * (nTime1 - nTimeStart), nPackagesSelected, nDescendantsUpdated, 0.001 * (nTime2 - nTime1), 0.001 * (nTime2 - nTimeStart)); return std::move(pblocktemplate); }
CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, int newConfirmTarget, bool specifiedConfirmTarget, CAmount totalFee, bool newTxReplaceable) : txid(std::move(txidIn)), nOldFee(0), nNewFee(0) { vErrors.clear(); bumpedTxid.SetNull(); AssertLockHeld(pWallet->cs_wallet); if (!pWallet->mapWallet.count(txid)) { vErrors.push_back("Invalid or non-wallet transaction id"); currentResult = BumpFeeResult::INVALID_ADDRESS_OR_KEY; return; } auto it = pWallet->mapWallet.find(txid); const CWalletTx& wtx = it->second; if (pWallet->HasWalletSpend(txid)) { vErrors.push_back("Transaction has descendants in the wallet"); currentResult = BumpFeeResult::INVALID_PARAMETER; return; } { LOCK(mempool.cs); auto it_mp = mempool.mapTx.find(txid); if (it_mp != mempool.mapTx.end() && it_mp->GetCountWithDescendants() > 1) { vErrors.push_back("Transaction has descendants in the mempool"); currentResult = BumpFeeResult::INVALID_PARAMETER; return; } } if (wtx.GetDepthInMainChain() != 0) { vErrors.push_back("Transaction has been mined, or is conflicted with a mined transaction"); currentResult = BumpFeeResult::WALLET_ERROR; return; } if (!SignalsOptInRBF(wtx)) { vErrors.push_back("Transaction is not BIP 125 replaceable"); currentResult = BumpFeeResult::WALLET_ERROR; return; } if (wtx.mapValue.count("replaced_by_txid")) { vErrors.push_back(strprintf("Cannot bump transaction %s which was already bumped by transaction %s", txid.ToString(), wtx.mapValue.at("replaced_by_txid"))); currentResult = BumpFeeResult::WALLET_ERROR; return; } // check that original tx consists entirely of our inputs // if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee) if (!pWallet->IsAllFromMe(wtx, ISMINE_SPENDABLE)) { vErrors.push_back("Transaction contains inputs that don't belong to this wallet"); currentResult = BumpFeeResult::WALLET_ERROR; return; } // figure out which output was change // if there was no change output or multiple change outputs, fail int nOutput = -1; for (size_t i = 0; i < wtx.tx->vout.size(); ++i) { if (pWallet->IsChange(wtx.tx->vout[i])) { if (nOutput != -1) { vErrors.push_back("Transaction has multiple change outputs"); currentResult = BumpFeeResult::WALLET_ERROR; return; } nOutput = i; } } if (nOutput == -1) { vErrors.push_back("Transaction does not have a change output"); currentResult = BumpFeeResult::WALLET_ERROR; return; } // Calculate the expected size of the new transaction. int64_t txSize = GetVirtualTransactionSize(*(wtx.tx)); const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx, pWallet); if (maxNewTxSize < 0) { vErrors.push_back("Transaction contains inputs that cannot be signed"); currentResult = BumpFeeResult::INVALID_ADDRESS_OR_KEY; return; } // calculate the old fee and fee-rate nOldFee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut(); CFeeRate nOldFeeRate(nOldFee, txSize); CFeeRate nNewFeeRate; // The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to // future proof against changes to network wide policy for incremental relay // fee that our node may not be aware of. CFeeRate walletIncrementalRelayFee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE); if (::incrementalRelayFee > walletIncrementalRelayFee) { walletIncrementalRelayFee = ::incrementalRelayFee; } if (totalFee > 0) { CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + ::incrementalRelayFee.GetFee(maxNewTxSize); if (totalFee < minTotalFee) { vErrors.push_back(strprintf("Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)", FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(::incrementalRelayFee.GetFee(maxNewTxSize)))); currentResult = BumpFeeResult::INVALID_PARAMETER; return; } CAmount requiredFee = CWallet::GetRequiredFee(maxNewTxSize); if (totalFee < requiredFee) { vErrors.push_back(strprintf("Insufficient totalFee (cannot be less than required fee %s)", FormatMoney(requiredFee))); currentResult = BumpFeeResult::INVALID_PARAMETER; return; } nNewFee = totalFee; nNewFeeRate = CFeeRate(totalFee, maxNewTxSize); } else { // if user specified a confirm target then don't consider any global payTxFee if (specifiedConfirmTarget) { nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, CAmount(0)); } // otherwise use the regular wallet logic to select payTxFee or default confirm target else { nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool); } nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize); // New fee rate must be at least old rate + minimum incremental relay rate // walletIncrementalRelayFee.GetFeePerK() should be exact, because it's initialized // in that unit (fee per kb). // However, nOldFeeRate is a calculated value from the tx fee/size, so // add 1 satoshi to the result, because it may have been rounded down. if (nNewFeeRate.GetFeePerK() < nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK()) { nNewFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK()); nNewFee = nNewFeeRate.GetFee(maxNewTxSize); } } // Check that in all cases the new fee doesn't violate maxTxFee if (nNewFee > maxTxFee) { vErrors.push_back(strprintf("Specified or calculated fee %s is too high (cannot be higher than maxTxFee %s)", FormatMoney(nNewFee), FormatMoney(maxTxFee))); currentResult = BumpFeeResult::WALLET_ERROR; return; } // check that fee rate is higher than mempool's minimum fee // (no point in bumping fee if we know that the new tx won't be accepted to the mempool) // This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps, // in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a // moment earlier. In this case, we report an error to the user, who may use totalFee to make an adjustment. CFeeRate minMempoolFeeRate = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); if (nNewFeeRate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) { vErrors.push_back(strprintf("New fee rate (%s) is less than the minimum fee rate (%s) to get into the mempool. totalFee value should to be at least %s or settxfee value should be at least %s to add transaction.", FormatMoney(nNewFeeRate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFee(maxNewTxSize)), FormatMoney(minMempoolFeeRate.GetFeePerK()))); currentResult = BumpFeeResult::WALLET_ERROR; return; } // Now modify the output to increase the fee. // If the output is not large enough to pay the fee, fail. CAmount nDelta = nNewFee - nOldFee; assert(nDelta > 0); mtx = *wtx.tx; CTxOut* poutput = &(mtx.vout[nOutput]); if (poutput->nValue < nDelta) { vErrors.push_back("Change output is too small to bump the fee"); currentResult = BumpFeeResult::WALLET_ERROR; return; } // If the output would become dust, discard it (converting the dust to fee) poutput->nValue -= nDelta; if (poutput->nValue <= poutput->GetDustThreshold(::dustRelayFee)) { LogPrint(BCLog::RPC, "Bumping fee and discarding dust output\n"); nNewFee += poutput->nValue; mtx.vout.erase(mtx.vout.begin() + nOutput); } // Mark new tx not replaceable, if requested. if (!newTxReplaceable) { for (auto& input : mtx.vin) { if (input.nSequence < 0xfffffffe) input.nSequence = 0xfffffffe; } } currentResult = BumpFeeResult::OK; }
bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockReward, std::string& strErrorRet) { strErrorRet = ""; bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward); if(fDebug) LogPrintf("block.vtx[0]->GetValueOut() %lld <= blockReward %lld\n", block.vtx[0]->GetValueOut(), blockReward); // we are still using budgets, but we have no data about them anymore, // all we know is predefined budget cycle and window const Consensus::Params& consensusParams = Params().GetConsensus(); if(nBlockHeight < consensusParams.nSuperblockStartBlock) { int nOffset = nBlockHeight % consensusParams.nBudgetPaymentsCycleBlocks; if(nBlockHeight >= consensusParams.nBudgetPaymentsStartBlock && nOffset < consensusParams.nBudgetPaymentsWindowBlocks) { // NOTE: old budget system is disabled since 12.1 if(masternodeSync.IsSynced()) { // no old budget blocks should be accepted here on mainnet, // testnet/devnet/regtest should produce regular blocks only LogPrint("gobject", "IsBlockValueValid -- WARNING: Client synced but old budget system is disabled, checking block value against block reward\n"); if(!isBlockRewardValueMet) { strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, old budgets are disabled", nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); } return isBlockRewardValueMet; } // when not synced, rely on online nodes (all networks) LogPrint("gobject", "IsBlockValueValid -- WARNING: Skipping old budget block value checks, accepting block\n"); return true; } // LogPrint("gobject", "IsBlockValueValid -- Block is not in budget cycle window, checking block value against block reward\n"); if(!isBlockRewardValueMet) { strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, block is not in old budget cycle window", nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); } return isBlockRewardValueMet; } // superblocks started CAmount nSuperblockMaxValue = blockReward + CSuperblock::GetPaymentsLimit(nBlockHeight); bool isSuperblockMaxValueMet = (block.vtx[0]->GetValueOut() <= nSuperblockMaxValue); LogPrint("gobject", "block.vtx[0]->GetValueOut() %lld <= nSuperblockMaxValue %lld\n", block.vtx[0]->GetValueOut(), nSuperblockMaxValue); if(!masternodeSync.IsSynced()) { // not enough data but at least it must NOT exceed superblock max value if(CSuperblock::IsValidBlockHeight(nBlockHeight)) { if(fDebug) LogPrintf("IsBlockPayeeValid -- WARNING: Client not synced, checking superblock max bounds only\n"); if(!isSuperblockMaxValueMet) { strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded superblock max value", nBlockHeight, block.vtx[0]->GetValueOut(), nSuperblockMaxValue); } return isSuperblockMaxValueMet; } if(!isBlockRewardValueMet) { strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, only regular blocks are allowed at this height", nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); } // it MUST be a regular block otherwise return isBlockRewardValueMet; } // we are synced, let's try to check as much data as we can if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) { if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) { if(CSuperblockManager::IsValid(*block.vtx[0], nBlockHeight, blockReward)) { LogPrint("gobject", "IsBlockValueValid -- Valid superblock at height %d: %s", nBlockHeight, block.vtx[0]->ToString()); // all checks are done in CSuperblock::IsValid, nothing to do here return true; } // triggered but invalid? that's weird LogPrintf("IsBlockValueValid -- ERROR: Invalid superblock detected at height %d: %s", nBlockHeight, block.vtx[0]->ToString()); // should NOT allow invalid superblocks, when superblocks are enabled strErrorRet = strprintf("invalid superblock detected at height %d", nBlockHeight); return false; } LogPrint("gobject", "IsBlockValueValid -- No triggered superblock detected at height %d\n", nBlockHeight); if(!isBlockRewardValueMet) { strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, no triggered superblock detected", nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); } } else { // should NOT allow superblocks at all, when superblocks are disabled LogPrint("gobject", "IsBlockValueValid -- Superblocks are disabled, no superblocks allowed\n"); if(!isBlockRewardValueMet) { strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, superblocks are disabled", nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); } } // it MUST be a regular block return isBlockRewardValueMet; }
void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval) { Check(); LOCK(cs); //remove inactive and outdated vector<CMasternode>::iterator it = vMasternodes.begin(); while(it != vMasternodes.end()){ if((*it).activeState == CMasternode::MASTERNODE_REMOVE || (*it).activeState == CMasternode::MASTERNODE_VIN_SPENT || (forceExpiredRemoval && (*it).activeState == CMasternode::MASTERNODE_EXPIRED) || (*it).protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) { LogPrint("masnernode", "CMasternodeMan: Removing inactive Masternode %s - %i now\n", (*it).addr.ToString(), size() - 1); //erase all of the broadcasts we've seen from this vin // -- if we missed a few pings and the node was removed, this will allow is to get it back without them // sending a brand new mnb map<uint256, CMasternodeBroadcast>::iterator it3 = mapSeenMasternodeBroadcast.begin(); while(it3 != mapSeenMasternodeBroadcast.end()){ if((*it3).second.vin == (*it).vin){ masternodeSync.mapSeenSyncMNB.erase((*it3).first); mapSeenMasternodeBroadcast.erase(it3++); } else { ++it3; } } // allow us to ask for this masternode again if we see another ping map<COutPoint, int64_t>::iterator it2 = mWeAskedForMasternodeListEntry.begin(); while(it2 != mWeAskedForMasternodeListEntry.end()){ if((*it2).first == (*it).vin.prevout){ mWeAskedForMasternodeListEntry.erase(it2++); } else { ++it2; } } it = vMasternodes.erase(it); } else { ++it; } } // check who's asked for the Masternode list map<CNetAddr, int64_t>::iterator it1 = mAskedUsForMasternodeList.begin(); while(it1 != mAskedUsForMasternodeList.end()){ if((*it1).second < GetTime()) { mAskedUsForMasternodeList.erase(it1++); } else { ++it1; } } // check who we asked for the Masternode list it1 = mWeAskedForMasternodeList.begin(); while(it1 != mWeAskedForMasternodeList.end()){ if((*it1).second < GetTime()){ mWeAskedForMasternodeList.erase(it1++); } else { ++it1; } } // check which Masternodes we've asked for map<COutPoint, int64_t>::iterator it2 = mWeAskedForMasternodeListEntry.begin(); while(it2 != mWeAskedForMasternodeListEntry.end()){ if((*it2).second < GetTime()){ mWeAskedForMasternodeListEntry.erase(it2++); } else { ++it2; } } }
void StartRPC() { LogPrint(BCLog::RPC, "Starting RPC\n"); fRPCRunning = true; g_rpcSignals.Started(); }
ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn) { if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty())) return READ_STATUS_INVALID; if (cmpctblock.shorttxids.size() + cmpctblock.prefilledtxn.size() > MAX_BLOCK_WEIGHT / MIN_SERIALIZABLE_TRANSACTION_WEIGHT) return READ_STATUS_INVALID; assert(header.IsNull() && txn_available.empty()); header = cmpctblock.header; txn_available.resize(cmpctblock.BlockTxCount()); int32_t lastprefilledindex = -1; for (size_t i = 0; i < cmpctblock.prefilledtxn.size(); i++) { if (cmpctblock.prefilledtxn[i].tx->IsNull()) return READ_STATUS_INVALID; lastprefilledindex += cmpctblock.prefilledtxn[i].index + 1; //index is a uint16_t, so can't overflow here if (lastprefilledindex > std::numeric_limits<uint16_t>::max()) return READ_STATUS_INVALID; if ((uint32_t)lastprefilledindex > cmpctblock.shorttxids.size() + i) { // If we are inserting a tx at an index greater than our full list of shorttxids // plus the number of prefilled txn we've inserted, then we have txn for which we // have neither a prefilled txn or a shorttxid! return READ_STATUS_INVALID; } txn_available[lastprefilledindex] = cmpctblock.prefilledtxn[i].tx; } prefilled_count = cmpctblock.prefilledtxn.size(); // Calculate map of txids -> positions and check mempool to see what we have (or don't) // Because well-formed cmpctblock messages will have a (relatively) uniform distribution // of short IDs, any highly-uneven distribution of elements can be safely treated as a // READ_STATUS_FAILED. std::unordered_map<uint64_t, uint16_t> shorttxids(cmpctblock.shorttxids.size()); uint16_t index_offset = 0; for (size_t i = 0; i < cmpctblock.shorttxids.size(); i++) { while (txn_available[i + index_offset]) index_offset++; shorttxids[cmpctblock.shorttxids[i]] = i + index_offset; // To determine the chance that the number of entries in a bucket exceeds N, // we use the fact that the number of elements in a single bucket is // binomially distributed (with n = the number of shorttxids S, and p = // 1 / the number of buckets), that in the worst case the number of buckets is // equal to S (due to std::unordered_map having a default load factor of 1.0), // and that the chance for any bucket to exceed N elements is at most // buckets * (the chance that any given bucket is above N elements). // Thus: P(max_elements_per_bucket > N) <= S * (1 - cdf(binomial(n=S,p=1/S), N)). // If we assume blocks of up to 16000, allowing 12 elements per bucket should // only fail once per ~1 million block transfers (per peer and connection). if (shorttxids.bucket_size(shorttxids.bucket(cmpctblock.shorttxids[i])) > 12) return READ_STATUS_FAILED; } // TODO: in the shortid-collision case, we should instead request both transactions // which collided. Falling back to full-block-request here is overkill. if (shorttxids.size() != cmpctblock.shorttxids.size()) return READ_STATUS_FAILED; // Short ID collision std::vector<bool> have_txn(txn_available.size()); { LOCK(pool->cs); const std::vector<std::pair<uint256, CTxMemPool::txiter> >& vTxHashes = pool->vTxHashes; for (size_t i = 0; i < vTxHashes.size(); i++) { uint64_t shortid = cmpctblock.GetShortID(vTxHashes[i].first); std::unordered_map<uint64_t, uint16_t>::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { if (!have_txn[idit->second]) { txn_available[idit->second] = vTxHashes[i].second->GetSharedTx(); have_txn[idit->second] = true; mempool_count++; } else { // If we find two mempool txn that match the short id, just request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying if (txn_available[idit->second]) { txn_available[idit->second].reset(); mempool_count--; } } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, // the performance win of an early exit here is too good to pass up and worth // the extra risk. if (mempool_count == shorttxids.size()) break; } } for (size_t i = 0; i < extra_txn.size(); i++) { uint64_t shortid = cmpctblock.GetShortID(extra_txn[i].first); std::unordered_map<uint64_t, uint16_t>::iterator idit = shorttxids.find(shortid); if (idit != shorttxids.end()) { if (!have_txn[idit->second]) { txn_available[idit->second] = extra_txn[i].second; have_txn[idit->second] = true; mempool_count++; extra_count++; } else { // If we find two mempool/extra txn that match the short id, just // request it. // This should be rare enough that the extra bandwidth doesn't matter, // but eating a round-trip due to FillBlock failure would be annoying // Note that we don't want duplication between extra_txn and mempool to // trigger this case, so we compare witness hashes first if (txn_available[idit->second] && txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) { txn_available[idit->second].reset(); mempool_count--; extra_count--; } } } // Though ideally we'd continue scanning for the two-txn-match-shortid case, // the performance win of an early exit here is too good to pass up and worth // the extra risk. if (mempool_count == shorttxids.size()) break; } LogPrint(BCLog::CMPCTBLOCK, "Initialized PartiallyDownloadedBlock for block %s using a cmpctblock of size %lu\n", cmpctblock.header.GetHash().ToString(), GetSerializeSize(cmpctblock, SER_NETWORK, PROTOCOL_VERSION)); return READ_STATUS_OK; }
void InterruptRPC() { LogPrint(BCLog::RPC, "Interrupting RPC\n"); // Interrupt e.g. running longpolls fRPCRunning = false; }
// partly copied from https://github.com/zcash/zcash/blob/master/src/miner.cpp#L581 bool equihash_(std::string solver, CBlock *pblock, int n, int k) { arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); // Hash state crypto_generichash_blake2b_state state; EhInitialiseState(n, k, state); // I = the block header minus nonce and solution. CEquihashInput I{*pblock}; CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << I; // H(I||... crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size()); // H(I||V||... crypto_generichash_blake2b_state curr_state; curr_state = state; crypto_generichash_blake2b_update(&curr_state, pblock->nNonce.begin(), pblock->nNonce.size()); // (x_1, x_2, ...) = A(I, V, n, k) LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n", solver, pblock->nNonce.ToString()); std::function<bool(std::vector<unsigned char>)> validBlock = [&pblock, &hashTarget](std::vector<unsigned char> soln) { // Write the solution to the hash and compute the result. pblock->nSolution = soln; if (UintToArith256(pblock->GetHash()) > hashTarget) { return false; } // Found a solution LogPrintf("CMMMiner:\n"); LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex()); return true; }; if (solver == "tromp") { // Create solver and initialize it. equi eq(1); eq.setstate(&curr_state); // Intialization done, start algo driver. eq.digit0(0); eq.xfull = eq.bfull = eq.hfull = 0; eq.showbsizes(0); for (u32 r = 1; r < WK; r++) { (r&1) ? eq.digitodd(r, 0) : eq.digiteven(r, 0); eq.xfull = eq.bfull = eq.hfull = 0; eq.showbsizes(r); } eq.digitK(0); // Convert solution indices to byte array (decompress) and pass it to validBlock method. for (size_t s = 0; s < eq.nsols; s++) { std::vector<eh_index> index_vector(PROOFSIZE); for (size_t i = 0; i < PROOFSIZE; i++) { index_vector[i] = eq.sols[s][i]; } std::vector<unsigned char> sol_char = GetMinimalFromIndices(index_vector, DIGITBITS); if (validBlock(sol_char)) return true; } } else { try { if (EhOptimisedSolve(n, k, curr_state, validBlock)) return true; } catch (std::exception&) { LogPrintf("pow/nano.cpp: ", "execption catched..."); } } return false; }
result nekoParticleInstance::LoadParticle(const char8 *fileName, bool forUseOnly) { char8 *fileData; TiXmlDocument doc; if(forUseOnly) { if(FAILED(GetNekoNovel()->GetFileSystem()->LoadData( (string("ÆÄƼŬ\\") + fileName).c_str(), &fileData))) return E_NOT_EXIST; doc.Parse(fileData); // ¸Þ¸ð¸® ¾ø¾Ö±â.. delete []fileData; mForUseOnly = true; } else { doc.LoadFile(fileName); } mFileName = fileName; if(doc.Error()) { LogPrint(LOG_LEVEL_WARN, "'%s' ÆÄÀÏÀº XML ±¸¹®ÀÌ À߸øµÇ¾ú½À´Ï´Ù.", fileName); return E_FAIL; } TiXmlElement *root = doc.FirstChildElement("NekoNovel_Particle"); if(!root) { LogPrint(LOG_LEVEL_WARN, "'%s' ÆÄÀÏ¿¡ ÆÄƼŬ Á¤º¸°¡ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.", fileName); return E_FAIL; } Clear(); TiXmlElement *emitter = root->FirstChildElement("Emitter"); TiXmlElement *events; TiXmlElement *event; while(emitter) { nekoParticleEmitter *emt = AddEmitter(emitter->Attribute("Name")); emt->mEmitDelay = atof(emitter->Attribute("EmitDelay")); emt->mMinDir.x = atof(emitter->Attribute("MinDirX")); emt->mMinDir.y = atof(emitter->Attribute("MinDirY")); emt->mMaxDir.x = atof(emitter->Attribute("MaxDirX")); emt->mMaxDir.y = atof(emitter->Attribute("MaxDirY")); emt->mMinScale = atof(emitter->Attribute("MinScale")); emt->mMaxScale = atof(emitter->Attribute("MaxScale")); emt->mMaxCount = atoi(emitter->Attribute("MaxCount")); emt->mLoop = stricmp(emitter->Attribute("Loop"), "true") == 0; emt->mSpawnPos.x = atof(emitter->Attribute("SpawnPosX")); emt->mSpawnPos.y = atof(emitter->Attribute("SpawnPosY")); emt->mSpawnRadius.x = atof(emitter->Attribute("SpawnRadiusX")); emt->mSpawnRadius.y = atof(emitter->Attribute("SpawnRadiusY")); emt->mMinLifeTime = atof(emitter->Attribute("MinLifeTime")); emt->mMaxLifeTime = atof(emitter->Attribute("MaxLifeTime")); if(emitter->Attribute("MinFirstAppearTime")) emt->mMinFirstAppearTime = atof(emitter->Attribute("MinFirstAppearTime")); if(emitter->Attribute("MaxFirstAppearTime")) emt->mMaxFirstAppearTime = atof(emitter->Attribute("MaxFirstAppearTime")); emt->mMinStartColor = _atoi64(emitter->Attribute("MinStartColor")); emt->mMaxStartColor = _atoi64(emitter->Attribute("MaxStartColor")); emt->mMinEndColor = _atoi64(emitter->Attribute("MinEndColor")); emt->mMaxEndColor = _atoi64(emitter->Attribute("MaxEndColor")); emt->mRotation = atof(emitter->Attribute("Rotation")); emt->mRotationSpeed = atof(emitter->Attribute("RotationSpeed")); emt->mScaleSpeed = atof(emitter->Attribute("ScaleSpeed")); emt->mGravity.x = atof(emitter->Attribute("GravityX")); emt->mGravity.y = atof(emitter->Attribute("GravityY")); emt->mSrcBlend = atoi(emitter->Attribute("SrcBlend")); emt->mDestBlend = atoi(emitter->Attribute("DestBlend")); emt->SetTexture(emitter->Attribute("Image")); events = emitter->FirstChildElement("Events"); if(events) { event = events->FirstChildElement("Event"); while(event) { nekoParticleEvent pevt; pevt.mTime = atof(event->Attribute("Time")); pevt.mFlags = atoi(event->Attribute("Flags")); pevt.mMinDir.x = atof(event->Attribute("MinDirX")); pevt.mMinDir.y = atof(event->Attribute("MinDirY")); pevt.mMaxDir.x = atof(event->Attribute("MaxDirX")); pevt.mMaxDir.y = atof(event->Attribute("MaxDirY")); pevt.mGravity.x = atof(event->Attribute("GravityX")); pevt.mGravity.y = atof(event->Attribute("GravityY")); pevt.mRotationSpeed = atof(event->Attribute("RotationSpeed")); pevt.mScaleSpeed = atof(event->Attribute("ScaleSpeed")); pevt.mColor = _atoi64(event->Attribute("Color")); emt->ImportEvent(pevt); event = event->NextSiblingElement("Event"); } } emt->FillNodes(); emitter = emitter->NextSiblingElement("Emitter"); } //LogPrint(LOG_LEVEL_INFO, "ÆÄƼŬ ºÒ·¯¿À±â°¡ ¿Ï·áµÇ¾ú½À´Ï´Ù. '%s'.", fileName); return S_OK; }
void zmqError(const char *str) { LogPrint("zmq", "zmq: Error: %s, errno=%s\n", str, zmq_strerror(errno)); }
bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled) { if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("CMasternodePing::CheckAndUpdate - Signature rejected, too far into the future %s\n", vin.ToString()); nDos = 1; return false; } if (sigTime <= GetAdjustedTime() - 60 * 60) { LogPrintf("CMasternodePing::CheckAndUpdate - Signature rejected, too far into the past %s - %d %d \n", vin.ToString(), sigTime, GetAdjustedTime()); nDos = 1; return false; } LogPrint("masternode", "CMasternodePing::CheckAndUpdate - New Ping - %s - %s - %lli\n", GetHash().ToString(), blockHash.ToString(), sigTime); // see if we have this Masternode CMasternode* pmn = mnodeman.Find(vin); if(pmn != NULL && pmn->protocolVersion >= masternodePayments.GetMinMasternodePaymentsProto()) { if (fRequireEnabled && !pmn->IsEnabled()) return false; // LogPrintf("mnping - Found corresponding mn for vin: %s\n", vin.ToString()); // update only if there is no known ping for this masternode or // last ping was more then MASTERNODE_MIN_MNP_SECONDS-60 ago comparing to this one if(!pmn->IsPingedWithin(MASTERNODE_MIN_MNP_SECONDS - 60, sigTime)) { std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime); std::string errorMessage = ""; if(!obfuScationSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)) { LogPrintf("CMasternodePing::CheckAndUpdate - Got bad Masternode address signature %s\n", vin.ToString()); nDos = 33; return false; } BlockMap::iterator mi = mapBlockIndex.find(blockHash); if (mi != mapBlockIndex.end() && (*mi).second) { if((*mi).second->nHeight < chainActive.Height() - 24) { LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is too old\n", vin.ToString(), blockHash.ToString()); // Do nothing here (no Masternode update, no mnping relay) // Let this node to be visible but fail to accept mnping return false; } } else { if (fDebug) LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is unknown\n", vin.ToString(), blockHash.ToString()); // maybe we stuck so we shouldn't ban this node, just fail to accept it // TODO: or should we also request this block? return false; } pmn->lastPing = *this; //mnodeman.mapSeenMasternodeBroadcast.lastPing is probably outdated, so we'll update it CMasternodeBroadcast mnb(*pmn); uint256 hash = mnb.GetHash(); if(mnodeman.mapSeenMasternodeBroadcast.count(hash)) { mnodeman.mapSeenMasternodeBroadcast[hash].lastPing = *this; } pmn->Check(true); if(!pmn->IsEnabled()) return false; LogPrint("masternode", "CMasternodePing::CheckAndUpdate - Masternode ping accepted, vin: %s\n", vin.ToString()); Relay(); return true; } LogPrint("masternode", "CMasternodePing::CheckAndUpdate - Masternode ping arrived too early, vin: %s\n", vin.ToString()); //nDos = 1; //disable, this is happening frequently and causing banned peers return false; } LogPrint("masternode", "CMasternodePing::CheckAndUpdate - Couldn't find compatible Masternode entry, vin: %s\n", vin.ToString()); return false; }
void DebugMessageHandler(QtMsgType type, const char *msg) { Q_UNUSED(type); LogPrint("qt", "GUI: %s\n", msg); }
void DebugMessageHandler(QtMsgType type, const char *msg) { const char *category = (type == QtDebugMsg) ? "qt" : NULL; LogPrint(category, "GUI: %s\n", msg); }
void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg) { Q_UNUSED(type); Q_UNUSED(context); LogPrint("qt", "GUI: %s\n", qPrintable(msg)); }
void TunnelPool::TestTunnels () { for (auto it: m_Tests) { LogPrint (eLogWarning, "Tunnels: test of tunnel ", it.first, " failed"); // if test failed again with another tunnel we consider it failed if (it.second.first) { if (it.second.first->GetState () == eTunnelStateTestFailed) { it.second.first->SetState (eTunnelStateFailed); std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (it.second.first); } else it.second.first->SetState (eTunnelStateTestFailed); } if (it.second.second) { if (it.second.second->GetState () == eTunnelStateTestFailed) { it.second.second->SetState (eTunnelStateFailed); { std::unique_lock<std::mutex> l(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } else it.second.second->SetState (eTunnelStateTestFailed); } } m_Tests.clear (); // new tests auto it1 = m_OutboundTunnels.begin (); auto it2 = m_InboundTunnels.begin (); while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) { bool failed = false; if ((*it1)->IsFailed ()) { failed = true; it1++; } if ((*it2)->IsFailed ()) { failed = true; it2++; } if (!failed) { uint32_t msgID; RAND_bytes ((uint8_t *)&msgID, 4); m_Tests[msgID] = std::make_pair (*it1, *it2); (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), CreateDeliveryStatusMsg (msgID)); it1++; it2++; } } }
bool CGovernanceObject::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, CGovernanceException& exception, CConnman* connman) { LOCK(cs_fobject); std::string strResult; // do not process already known valid votes twice if (fileVotes.HasVote(vote.GetHash())) { // nothing to do here, not an error strResult = "CGovernanceObject::ProcessVote -- Already known valid vote"; LogPrint(BCLog::GOV, "%s\n", strResult); exception = CGovernanceException(strResult, GOVERNANCE_EXCEPTION_NONE); return false; } if (!mnodeman.Has(vote.GetMasternodeOutpoint())) { strResult = strprintf("CGovernanceObject::ProcessVote -- Masternode " + vote.GetMasternodeOutpoint().ToStringShort() + " not found"); LogPrint(BCLog::GOV, "%s\n", strResult); exception = CGovernanceException(strResult, GOVERNANCE_EXCEPTION_WARNING); if (cmmapOrphanVotes.Insert(vote.GetMasternodeOutpoint(), vote_time_pair_t(vote, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME))) { if (pfrom) { mnodeman.AskForMN(pfrom, vote.GetMasternodeOutpoint(), connman); } LogPrintf("%s\n", strResult); } else { LogPrint(BCLog::GOV, "%s\n", strResult); } return false; } vote_m_it it = mapCurrentMNVotes.emplace(vote_m_t::value_type(vote.GetMasternodeOutpoint(), vote_rec_t())).first; vote_rec_t& voteRecordRef = it->second; vote_signal_enum_t eSignal = vote.GetSignal(); if (eSignal == VOTE_SIGNAL_NONE) { strResult = "CGovernanceObject::ProcessVote -- Vote signal: none"; LogPrint(BCLog::GOV, "%s\n", strResult); exception = CGovernanceException(strResult, GOVERNANCE_EXCEPTION_WARNING); return false; } if (eSignal > MAX_SUPPORTED_VOTE_SIGNAL) { strResult = strprintf("CGovernanceObject::ProcessVote -- Unsupported vote signal: " + CGovernanceVoting::ConvertSignalToString(vote.GetSignal())); LogPrintf("%s\n", strResult); exception = CGovernanceException(strResult, GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20); return false; } vote_instance_m_it it2 = voteRecordRef.mapInstances.emplace(vote_instance_m_t::value_type(int(eSignal), vote_instance_t())).first; vote_instance_t& voteInstanceRef = it2->second; // Reject obsolete votes if (vote.GetTimestamp() < voteInstanceRef.nCreationTime) { strResult = "CGovernanceObject::ProcessVote -- Obsolete vote"; LogPrint(BCLog::GOV, "%s\n", strResult); exception = CGovernanceException(strResult, GOVERNANCE_EXCEPTION_NONE); return false; } int64_t nNow = GetAdjustedTime(); int64_t nVoteTimeUpdate = voteInstanceRef.nTime; if (governance.AreRateChecksEnabled()) { int64_t nTimeDelta = nNow - voteInstanceRef.nTime; if (nTimeDelta < GOVERNANCE_UPDATE_MIN) { strResult = strprintf("CGovernanceObject::ProcessVote -- Masternode voting too often, MN outpoint = " + vote.GetMasternodeOutpoint().ToStringShort() + ", governance object hash = " + GetHash().ToString() + ", time delta = %d", nTimeDelta); LogPrint(BCLog::GOV, "%s\n", strResult); exception = CGovernanceException(strResult, GOVERNANCE_EXCEPTION_TEMPORARY_ERROR); nVoteTimeUpdate = nNow; return false; } } // Finally check that the vote is actually valid (done last because of cost of signature verification) if (!vote.IsValid(true)) { strResult = strprintf("CGovernanceObject::ProcessVote -- Invalid vote, MN outpoint = " + vote.GetMasternodeOutpoint().ToStringShort() + ", governance object hash = " + GetHash().ToString() + ", vote hash = " + vote.GetHash().ToString()); LogPrintf("%s\n", strResult); exception = CGovernanceException(strResult, GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20); governance.AddInvalidVote(vote); return false; } if (!mnodeman.AddGovernanceVote(vote.GetMasternodeOutpoint(), vote.GetParentHash())) { strResult = strprintf("CGovernanceObject::ProcessVote -- Unable to add governance vote, MN outpoint = " + vote.GetMasternodeOutpoint().ToStringShort() + ", governance object hash = " + GetHash().ToString()); LogPrint(BCLog::GOV, "%s\n", strResult); exception = CGovernanceException(strResult, GOVERNANCE_EXCEPTION_PERMANENT_ERROR); return false; } voteInstanceRef = vote_instance_t(vote.GetOutcome(), nVoteTimeUpdate, vote.GetTimestamp()); fileVotes.AddVote(vote); fDirtyCache = true; return true; }