From edc61d62772ca42428b12815406eb27be7794416 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 19 Aug 2017 02:06:56 -0700 Subject: [PATCH 001/166] New way to verify beacon contract for AcceptToMemoryPool And CheckBlock --- src/main.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 950ca8928d..2a8e5e7e30 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ #include #include +bool VerifyBeaconContractTx(const std::string& txhashBoinc); extern std::string NodeAddress(CNode* pfrom); extern std::string ConvertBinToHex(std::string a); extern std::string ConvertHexToBin(std::string a); @@ -1379,7 +1380,6 @@ bool CTransaction::CheckTransaction() const if (!MoneyRange(nValueOut)) return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range")); } - // Check for duplicate inputs set vInOutPoints; BOOST_FOREACH(const CTxIn& txin, vin) @@ -1400,7 +1400,6 @@ bool CTransaction::CheckTransaction() const if (txin.prevout.IsNull()) return DoS(10, error("CTransaction::CheckTransaction() : prevout is null")); } - return true; } @@ -1443,6 +1442,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool* pfMissingInput if (!tx.CheckTransaction()) return error("AcceptToMemoryPool : CheckTransaction failed"); + // Verify beacon contract in tx if found + if (!VerifyBeaconContractTx(tx.hashBoinc)) + return tx.DoS(25, "AcceptToMemoryPool : bad beacon contract in tx; rejected"); + // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) return tx.DoS(100, error("AcceptToMemoryPool : coinbase as individual tx")); @@ -3964,7 +3967,6 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh for (unsigned int i = 1; i < vtx.size(); i++) if (vtx[i].IsCoinBase()) return DoS(100, error("CheckBlock[] : more than one coinbase")); - //Research Age MiningCPID bb = DeserializeBoincBlock(vtx[0].hashBoinc,nVersion); //For higher security, plus lets catch these bad blocks before adding them to the chain to prevent reorgs: @@ -4106,6 +4108,10 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh // ppcoin: check transaction timestamp if (GetBlockTime() < (int64_t)tx.nTime) return DoS(50, error("CheckBlock[] : block timestamp earlier than transaction timestamp")); + + // Verify beacon contract if a transaction contains a beacon contract + if (!VerifyBeaconContractTx(tx.hashBoinc)) + return DoS(25, "CheckBlock[] : bad beacon contract found in tx contained within block; rejected"); } // Check for duplicate txids. This is caught by ConnectInputs(), @@ -9188,3 +9194,44 @@ std::string GetBackupFilename(const std::string& basename, const std::string& su ? basename + "-" + std::string(boTime) : basename + "-" + std::string(boTime) + "-" + suffix; } + +bool VerifyBeaconContractTx(const std::string& txhashBoinc) +{ + // Check if tx contains beacon advertisement and evaluate for certain conditions + std::string chkMessageType = ExtractXML(txhashBoinc, "", ""); + std::string chkMessageAction = ExtractXML(txhashBoinc, "", ""); + if (chkMessageAction != "A" && chkMessageType != "beacon") + return true; // Not beacon contract + std::string chkMessageContract = ExtractXML(txhashBoinc, "", ""); + std::string chkMessageContractCPID = ExtractXML(txhashBoinc, "", ""); + // Here we GetBeaconElements for the contract in the tx + std::string tx_out_cpid; + std::string tx_out_address; + std::string tx_out_publickey; + GetBeaconElements(chkMessageContract, tx_out_cpid, tx_out_address, tx_out_publickey); + if (tx_out_cpid == "" || tx_out_address == "" || tx_out_publickey == "" || chkMessageContractCPID == "") + return false; + std::string chkKey = "beacon;" + chkMessageContractCPID; + std::string chkValue = mvApplicationCache[chkKey]; + int64_t chkiAge = pindexBest != NULL + ? pindexBest->nTime - mvApplicationCacheTimestamp[chkKey] + : 0; + int64_t chkSecondsBase = 60 * 24 * 30 * 60; + // Conditions + // Condition a) if beacon is younger then 5 months deny tx + if (chkiAge <= chkSecondsBase * 5 && chkiAge >= 1) + return false; + // Condition b) if beacon is younger then 6 months but older then 5 months verify using the same keypair; if not deny tx + if (chkiAge >= chkSecondsBase * 5 && chkiAge <= chkSecondsBase * 6) + { + std::string chk_out_cpid; + std::string chk_out_address; + std::string chk_out_publickey; + // Here we GetBeaconElements for the contract in the current beacon in chain + GetBeaconElements(chkValue, chk_out_cpid, chk_out_address, chk_out_publickey); + if (tx_out_publickey != chk_out_publickey) + return false; + } + // Passed checks + return true; +} From a1203843c2f1c274b6e950ff2fd6412bd436e687 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 19 Aug 2017 19:13:27 -0700 Subject: [PATCH 002/166] Fixed 2 error bugs and don't check beacon contracts in tx's in checkblock if loading index --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2a8e5e7e30..e0555d0a42 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1444,7 +1444,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool* pfMissingInput // Verify beacon contract in tx if found if (!VerifyBeaconContractTx(tx.hashBoinc)) - return tx.DoS(25, "AcceptToMemoryPool : bad beacon contract in tx; rejected"); + return tx.DoS(25, error("AcceptToMemoryPool : bad beacon contract in tx; rejected")); // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) @@ -4110,8 +4110,8 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh return DoS(50, error("CheckBlock[] : block timestamp earlier than transaction timestamp")); // Verify beacon contract if a transaction contains a beacon contract - if (!VerifyBeaconContractTx(tx.hashBoinc)) - return DoS(25, "CheckBlock[] : bad beacon contract found in tx contained within block; rejected"); + if (!VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) + return DoS(25, error("CheckBlock[] : bad beacon contract found in tx contained within block; rejected")); } // Check for duplicate txids. This is caught by ConnectInputs(), From fca40b223915699c666888985d5950c4a6d7c3c5 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sun, 20 Aug 2017 13:57:51 -0700 Subject: [PATCH 003/166] Move to beacon.cpp/h --- src/beacon.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ src/beacon.h | 2 ++ src/main.cpp | 42 ------------------------------------------ 3 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/beacon.cpp b/src/beacon.cpp index 37b7f99d21..b9255b67c5 100755 --- a/src/beacon.cpp +++ b/src/beacon.cpp @@ -10,6 +10,8 @@ extern bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std:: std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxSeconds); int64_t GetRSAWeightByCPIDWithRA(std::string cpid); +std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); + namespace { std::string GetNetSuffix() @@ -134,3 +136,44 @@ std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxS ? "" : value; } + +bool VerifyBeaconContractTx(const std::string& txhashBoinc) +{ + // Check if tx contains beacon advertisement and evaluate for certain conditions + std::string chkMessageType = ExtractXML(txhashBoinc, "", ""); + std::string chkMessageAction = ExtractXML(txhashBoinc, "", ""); + if (chkMessageAction != "A" && chkMessageType != "beacon") + return true; // Not beacon contract + std::string chkMessageContract = ExtractXML(txhashBoinc, "", ""); + std::string chkMessageContractCPID = ExtractXML(txhashBoinc, "", ""); + // Here we GetBeaconElements for the contract in the tx + std::string tx_out_cpid; + std::string tx_out_address; + std::string tx_out_publickey; + GetBeaconElements(chkMessageContract, tx_out_cpid, tx_out_address, tx_out_publickey); + if (tx_out_cpid == "" || tx_out_address == "" || tx_out_publickey == "" || chkMessageContractCPID == "") + return false; + std::string chkKey = "beacon;" + chkMessageContractCPID; + std::string chkValue = mvApplicationCache[chkKey]; + int64_t chkiAge = pindexBest != NULL + ? pindexBest->nTime - mvApplicationCacheTimestamp[chkKey] + : 0; + int64_t chkSecondsBase = 60 * 24 * 30 * 60; + // Conditions + // Condition a) if beacon is younger then 5 months deny tx + if (chkiAge <= chkSecondsBase * 5 && chkiAge >= 1) + return false; + // Condition b) if beacon is younger then 6 months but older then 5 months verify using the same keypair; if not deny tx + if (chkiAge >= chkSecondsBase * 5 && chkiAge <= chkSecondsBase * 6) + { + std::string chk_out_cpid; + std::string chk_out_address; + std::string chk_out_publickey; + // Here we GetBeaconElements for the contract in the current beacon in chain + GetBeaconElements(chkValue, chk_out_cpid, chk_out_address, chk_out_publickey); + if (tx_out_publickey != chk_out_publickey) + return false; + } + // Passed checks + return true; +} diff --git a/src/beacon.h b/src/beacon.h index 6ce58cccfd..c19a8d6cbc 100755 --- a/src/beacon.h +++ b/src/beacon.h @@ -62,3 +62,5 @@ void GetBeaconElements(const std::string& sBeacon, std::string& out_cpid, std::s std::string GetBeaconPublicKey(const std::string& cpid, bool bAdvertisingBeacon); int64_t BeaconTimeStamp(const std::string& cpid, bool bZeroOutAfterPOR); bool HasActiveBeacon(const std::string& cpid); + +bool VerifyBeaconContractTx(const std::string& txhashBoinc); diff --git a/src/main.cpp b/src/main.cpp index e0555d0a42..1f94bb871f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,7 +36,6 @@ #include #include -bool VerifyBeaconContractTx(const std::string& txhashBoinc); extern std::string NodeAddress(CNode* pfrom); extern std::string ConvertBinToHex(std::string a); extern std::string ConvertHexToBin(std::string a); @@ -9194,44 +9193,3 @@ std::string GetBackupFilename(const std::string& basename, const std::string& su ? basename + "-" + std::string(boTime) : basename + "-" + std::string(boTime) + "-" + suffix; } - -bool VerifyBeaconContractTx(const std::string& txhashBoinc) -{ - // Check if tx contains beacon advertisement and evaluate for certain conditions - std::string chkMessageType = ExtractXML(txhashBoinc, "", ""); - std::string chkMessageAction = ExtractXML(txhashBoinc, "", ""); - if (chkMessageAction != "A" && chkMessageType != "beacon") - return true; // Not beacon contract - std::string chkMessageContract = ExtractXML(txhashBoinc, "", ""); - std::string chkMessageContractCPID = ExtractXML(txhashBoinc, "", ""); - // Here we GetBeaconElements for the contract in the tx - std::string tx_out_cpid; - std::string tx_out_address; - std::string tx_out_publickey; - GetBeaconElements(chkMessageContract, tx_out_cpid, tx_out_address, tx_out_publickey); - if (tx_out_cpid == "" || tx_out_address == "" || tx_out_publickey == "" || chkMessageContractCPID == "") - return false; - std::string chkKey = "beacon;" + chkMessageContractCPID; - std::string chkValue = mvApplicationCache[chkKey]; - int64_t chkiAge = pindexBest != NULL - ? pindexBest->nTime - mvApplicationCacheTimestamp[chkKey] - : 0; - int64_t chkSecondsBase = 60 * 24 * 30 * 60; - // Conditions - // Condition a) if beacon is younger then 5 months deny tx - if (chkiAge <= chkSecondsBase * 5 && chkiAge >= 1) - return false; - // Condition b) if beacon is younger then 6 months but older then 5 months verify using the same keypair; if not deny tx - if (chkiAge >= chkSecondsBase * 5 && chkiAge <= chkSecondsBase * 6) - { - std::string chk_out_cpid; - std::string chk_out_address; - std::string chk_out_publickey; - // Here we GetBeaconElements for the contract in the current beacon in chain - GetBeaconElements(chkValue, chk_out_cpid, chk_out_address, chk_out_publickey); - if (tx_out_publickey != chk_out_publickey) - return false; - } - // Passed checks - return true; -} From 852fad404dbaf2286f3e417c336aef4288bfef08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 3 Sep 2017 20:18:19 +0200 Subject: [PATCH 004/166] Attempt to fix ClearCache. #576 --- src/main.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fbee229b8d..07c860b09f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5723,8 +5723,8 @@ bool ComputeNeuralNetworkSupermajorityHashes() if (mvCurrentNeuralNetworkHash.size() > 0) mvCurrentNeuralNetworkHash.clear(); //Clear the votes - WriteCache("neuralsecurity","pending","0",GetAdjustedTime()); ClearCache("neuralsecurity"); + WriteCache("neuralsecurity","pending","0",GetAdjustedTime()); try { int nMaxDepth = nBestHeight; @@ -8427,18 +8427,13 @@ void ClearCache(std::string section) { for(map::iterator ii=mvApplicationCache.begin(); ii!=mvApplicationCache.end(); ++ii) { - std::string key_section = mvApplicationCache[(*ii).first]; - if (key_section.length() > section.length()) + const std::string& key_section = (*ii).first; + if (boost::algorithm::starts_with(key_section, section)) { - if (key_section.substr(0,section.length())==section) - { - printf("\r\nClearing the cache....of value %s \r\n",mvApplicationCache[key_section].c_str()); mvApplicationCache[key_section]=""; mvApplicationCacheTimestamp[key_section]=1; - } } } - } From 958aec56e29ce7191cd22ecd42fa2fa910ac43e5 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 10 Aug 2017 20:16:22 +0200 Subject: [PATCH 005/166] Replace repetitive application cache iteration with an iterator:ish class. --- gridcoinresearch.pro | 6 +- src/Makefile.include.objs | 4 +- src/appcache.cpp | 28 ++++ src/appcache.h | 52 ++++++ src/rpcblockchain.cpp | 342 +++++++++++++++++--------------------- 5 files changed, 235 insertions(+), 197 deletions(-) create mode 100644 src/appcache.cpp create mode 100644 src/appcache.h diff --git a/gridcoinresearch.pro b/gridcoinresearch.pro index 23e69f1f66..6ebba2c751 100755 --- a/gridcoinresearch.pro +++ b/gridcoinresearch.pro @@ -270,7 +270,8 @@ HEADERS += src/qt/bitcoingui.h \ src/threadsafety.h \ src/cpid.h \ src/upgrader.h \ - src/boinc.h + src/boinc.h \ + src/appcache.h SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ @@ -349,7 +350,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/cpid.cpp \ src/upgrader.cpp \ src/boinc.cpp \ - src/allocators.cpp + src/allocators.cpp \ + src/appcache.cpp ## #RC_FILE = qaxserver.rc diff --git a/src/Makefile.include.objs b/src/Makefile.include.objs index 07b4d6d68b..69e593e0d9 100755 --- a/src/Makefile.include.objs +++ b/src/Makefile.include.objs @@ -38,5 +38,5 @@ OBJS= \ obj/block.o \ obj/beacon.o \ obj/boinc.o \ - obj/allocators.o - + obj/allocators.o \ + obj/appcache.o diff --git a/src/appcache.cpp b/src/appcache.cpp new file mode 100644 index 0000000000..783317bd29 --- /dev/null +++ b/src/appcache.cpp @@ -0,0 +1,28 @@ +#include "appcache.h" +#include "main.h" + +#include +#include + +AppCacheIterator::AppCacheIterator(const std::string& key) + : _begin(mvApplicationCache.begin()) + , _end(mvApplicationCache.end()) +{ + auto predicate = [key](typename AppCache::const_reference t) + { + return boost::algorithm::starts_with(t.first, key); + }; + + // Find the first occurrence of 'key' + _begin = std::find_if(_begin, _end, predicate); +} + +AppCache::iterator AppCacheIterator::begin() +{ + return _begin; +} + +AppCache::iterator AppCacheIterator::end() +{ + return _end; +} diff --git a/src/appcache.h b/src/appcache.h new file mode 100644 index 0000000000..6dca2a3163 --- /dev/null +++ b/src/appcache.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include + +//! +//! \brief Application cache type. +//! +typedef std::map AppCache; + +//! +//! \brief Application cache data key iterator. +//! +//! An iterator like class which can be used to iterate through the application +//! in ranged based for loops based on keys. For example, to iterate through +//! all the cached polls: +//! +//! \code +//! for(const auto& item : AppCacheIterator("poll") +//! { +//! const std::string& poll_name = item.second; +//! } +//! \endcode +//! +class AppCacheIterator +{ +public: + //! + //! \brief Constructor. + //! \param key Key to search for. For legacy code compatibility reasons + //! \p key is matched to the start of the cached key, so \a poll will + //! iterate over items with the key \a polls as well. + //! + AppCacheIterator(const std::string& key); + + //! + //! \brief Get iterator to first matching element. + //! \return Iterator pointing to the first matching element, or end() + //! if none is found. + //! + AppCache::iterator begin(); + + //! + //! \brief Get iterator to the element after the last element. + //! \return End iterator element. + //! + AppCache::iterator end(); + +private: + AppCache::iterator _begin; + AppCache::iterator _end; +}; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 730a775279..2ede06fa20 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -12,6 +12,7 @@ #include "txdb.h" #include "beacon.h" #include "util.h" +#include "appcache.h" #include #include @@ -876,21 +877,18 @@ double GetCountOf(std::string datatype) std::string GetListOf(std::string datatype) { std::string rows; - for(const auto& item : mvApplicationCache) + for(const auto& item : AppCacheIterator(datatype)) { const std::string& key_name = item.first; - if (boost::algorithm::starts_with(key_name, datatype)) - { - const std::string& key_value = item.second; - const std::string& subkey = key_name.substr(datatype.length()+1,key_name.length()-datatype.length()-1); - std::string row = subkey + "" + key_value; + const std::string& key_value = item.second; + const std::string& subkey = key_name.substr(datatype.length()+1,key_name.length()-datatype.length()-1); + std::string row = subkey + "" + key_value; - if (datatype=="beacon" && Contains(row,"INVESTOR")) - continue; + if (datatype=="beacon" && Contains(row,"INVESTOR")) + continue; - if (!row.empty()) - rows += row + ""; - } + if (!row.empty()) + rows += row + ""; } return rows; @@ -2316,19 +2314,9 @@ Value execute(const Array& params, bool fHelp) { std::string sType = params[1].get_str(); entry.push_back(Pair("Key Type",sType)); - for(map::iterator ii=mvApplicationCache.begin(); ii!=mvApplicationCache.end(); ++ii) - { - std::string key_name = (*ii).first; - if (key_name.length() > sType.length()) - { - if (key_name.substr(0,sType.length())==sType) - { - std::string key_value = mvApplicationCache[(*ii).first]; - entry.push_back(Pair(key_name,key_value)); - } - - } - } + for(const auto& item : AppCacheIterator(sType)) + entry.push_back(Pair(item.first, item.second)); + results.push_back(entry); } @@ -2864,16 +2852,12 @@ std::string SignBlockWithCPID(std::string sCPID, std::string sBlockHash) std::string GetPollContractByTitle(std::string objecttype, std::string title) { - for(const auto& item : mvApplicationCache) + for(const auto& item : AppCacheIterator(objecttype)) { - const std::string& key_name = item.first; const std::string& contract = item.second; - if (boost::algorithm::starts_with(key_name, objecttype)) - { - const std::string& PollTitle = ExtractXML(contract,"",""); - if(boost::iequals(PollTitle, title)) - return contract; - } + const std::string& PollTitle = ExtractXML(contract,"",""); + if(boost::iequals(PollTitle, title)) + return contract; } return std::string(); @@ -2964,28 +2948,22 @@ double VotesCount(std::string pollname, std::string answer, double sharetype, do { double total_shares = 0; out_participants = 0; - std::string objecttype="vote"; double MoneySupplyFactor = GetMoneySupplyFactor(); - for(const auto& item : mvApplicationCache) + for(const auto& item : AppCacheIterator("vote")) { - const std::string& key_name = item.first; const std::string& contract = item.second; - - if (boost::algorithm::starts_with(key_name, objecttype)) + const std::string& Title = ExtractXML(contract,"",""); + const std::string& VoterAnswer = ExtractXML(contract,"",""); + const std::vector& vVoterAnswers = split(VoterAnswer.c_str(),";"); + for (const std::string& voterAnswers : vVoterAnswers) { - const std::string& Title = ExtractXML(contract,"",""); - const std::string& VoterAnswer = ExtractXML(contract,"",""); - const std::vector& vVoterAnswers = split(VoterAnswer.c_str(),";"); - for (const std::string& voterAnswers : vVoterAnswers) + if (boost::iequals(pollname, Title) && boost::iequals(answer, voterAnswers)) { - if (boost::iequals(pollname, Title) && boost::iequals(answer, voterAnswers)) - { - double shares = PollCalculateShares(contract, sharetype, MoneySupplyFactor, vVoterAnswers.size()); - total_shares += shares; - out_participants += 1.0 / vVoterAnswers.size(); - } + double shares = PollCalculateShares(contract, sharetype, MoneySupplyFactor, vVoterAnswers.size()); + total_shares += shares; + out_participants += 1.0 / vVoterAnswers.size(); } } } @@ -3438,7 +3416,6 @@ Array GetJsonVoteDetailsReport(std::string pollname) double participants = 0; double MoneySupplyFactor = GetMoneySupplyFactor(); - std::string objecttype="vote"; Array results; Object entry; entry.push_back(Pair("Votes","Votes Report " + pollname)); @@ -3448,36 +3425,32 @@ Array GetJsonVoteDetailsReport(std::string pollname) entry.push_back(Pair("GRCAddress,CPID,Question,Answer,ShareType,URL", "Shares")); boost::to_lower(pollname); - for(const auto& item : mvApplicationCache) + for(const auto& item : AppCacheIterator("vote")) { - const std::string& key_name = item.first; const std::string& contract = item.second; - if (boost::algorithm::starts_with(key_name, objecttype)) + const std::string& Title = ExtractXML(contract,"",""); + if(boost::iequals(pollname, Title)) { - const std::string& Title = ExtractXML(contract,"",""); - if(boost::iequals(pollname, Title)) - { - const std::string& OriginalContract = GetPollContractByTitle("poll",Title); - const std::string& Question = ExtractXML(OriginalContract,"",""); - const std::string& GRCAddress = ExtractXML(contract,"",""); - const std::string& CPID = ExtractXML(contract,"",""); + const std::string& OriginalContract = GetPollContractByTitle("poll",Title); + const std::string& Question = ExtractXML(OriginalContract,"",""); + const std::string& GRCAddress = ExtractXML(contract,"",""); + const std::string& CPID = ExtractXML(contract,"",""); - double dShareType = cdbl(GetPollXMLElementByPollTitle(Title,"",""),0); - std::string sShareType= GetShareType(dShareType); - std::string sURL = ExtractXML(contract,"",""); + double dShareType = cdbl(GetPollXMLElementByPollTitle(Title,"",""),0); + std::string sShareType= GetShareType(dShareType); + std::string sURL = ExtractXML(contract,"",""); - std::string Balance = ExtractXML(contract,"",""); + std::string Balance = ExtractXML(contract,"",""); - const std::string& VoterAnswer = boost::to_lower_copy(ExtractXML(contract,"","")); - const std::vector& vVoterAnswers = split(VoterAnswer.c_str(),";"); - for (const auto& answer : vVoterAnswers) - { - double shares = PollCalculateShares(contract, dShareType, MoneySupplyFactor, vVoterAnswers.size()); - total_shares += shares; - participants += 1.0 / vVoterAnswers.size(); - const std::string& voter = GRCAddress + "," + CPID + "," + Question + "," + answer + "," + sShareType + "," + sURL; - entry.push_back(Pair(voter,RoundToString(shares,0))); - } + const std::string& VoterAnswer = boost::to_lower_copy(ExtractXML(contract,"","")); + const std::vector& vVoterAnswers = split(VoterAnswer.c_str(),";"); + for (const auto& answer : vVoterAnswers) + { + double shares = PollCalculateShares(contract, dShareType, MoneySupplyFactor, vVoterAnswers.size()); + total_shares += shares; + participants += 1.0 / vVoterAnswers.size(); + const std::string& voter = GRCAddress + "," + CPID + "," + Question + "," + answer + "," + sShareType + "," + sURL; + entry.push_back(Pair(voter,RoundToString(shares,0))); } } } @@ -3505,82 +3478,77 @@ Array GetJSONPollsReport(bool bDetail, std::string QueryByTitle, std::string& ou std::string sExportRow; out_export.clear(); - for(const auto& item : mvApplicationCache) + for(const auto& item : AppCacheIterator(datatype)) { const std::string& key_name = item.first; const std::string& contract = item.second; - if (boost::algorithm::starts_with(key_name, datatype)) + // Creating polls also create additional cache instances with ";burnamount" and ";recipient" + // appended. Skip all keys containing those fields. + if(boost::iends_with(key_name, ";burnamount") || + boost::iends_with(key_name, ";recipient")) + continue; + + std::string Title = key_name.substr(datatype.length()+1,key_name.length()-datatype.length()-1); + std::string Expiration = ExtractXML(contract,"",""); + std::string Question = ExtractXML(contract,"",""); + std::string Answers = ExtractXML(contract,"",""); + std::string ShareType = ExtractXML(contract,"",""); + std::string sURL = ExtractXML(contract,"",""); + boost::to_lower(Title); + if (!PollExpired(Title) || IncludeExpired) { - // Creating polls also create additional cache instances with ";burnamount" and ";recipient" - // appended. Skip all keys containing those fields. - if(boost::iends_with(key_name, ";burnamount") || - boost::iends_with(key_name, ";recipient")) - continue; - - std::string Title = key_name.substr(datatype.length()+1,key_name.length()-datatype.length()-1); - std::string Expiration = ExtractXML(contract,"",""); - std::string Question = ExtractXML(contract,"",""); - std::string Answers = ExtractXML(contract,"",""); - std::string ShareType = ExtractXML(contract,"",""); - std::string sURL = ExtractXML(contract,"",""); - boost::to_lower(Title); - - // TODO: Pass contract instead of title to PollExpired - if (!PollExpired(Title) || IncludeExpired) + if (QueryByTitle.empty() || QueryByTitle == Title) { - if (QueryByTitle.empty() || QueryByTitle == Title) + iPollNumber++; + total_participants = 0; + total_shares=0; + std::string BestAnswer; + double highest_share = 0; + std::string ExpirationDate = TimestampToHRDate(cdbl(Expiration,0)); + std::string sShareType = GetShareType(cdbl(ShareType,0)); + std::string TitleNarr = "Poll #" + RoundToString((double)iPollNumber,0) + + " (" + ExpirationDate + " ) - " + sShareType; + + entry.push_back(Pair(TitleNarr,Title)); + sExportRow = "" + sURL + "" + Title + "" + ExpirationDate + "" + sShareType + "" + Question + ""+Answers+""; + + if (bDetail) { - iPollNumber++; - total_participants = 0; - total_shares=0; - std::string BestAnswer; - double highest_share = 0; - std::string ExpirationDate = TimestampToHRDate(cdbl(Expiration,0)); - std::string sShareType = GetShareType(cdbl(ShareType,0)); - std::string TitleNarr = "Poll #" + RoundToString((double)iPollNumber,0) - + " (" + ExpirationDate + " ) - " + sShareType; - - entry.push_back(Pair(TitleNarr,Title)); - sExportRow = "" + sURL + "" + Title + "" + ExpirationDate + "" + sShareType + "" + Question + ""+Answers+""; - - if (bDetail) + entry.push_back(Pair("Question",Question)); + const std::vector& vAnswers = split(Answers.c_str(),";"); + sExportRow += ""; + size_t i = 0; + for (const std::string& answer : vAnswers) { - entry.push_back(Pair("Question",Question)); - const std::vector& vAnswers = split(Answers.c_str(),";"); - sExportRow += ""; - size_t i = 0; - for (const std::string& answer : vAnswers) + double participants=0; + double dShares = VotesCount(Title, answer, cdbl(ShareType,0),participants); + if (dShares > highest_share) { - double participants=0; - double dShares = VotesCount(Title, answer, cdbl(ShareType,0),participants); - if (dShares > highest_share) - { - highest_share = dShares; - BestAnswer = answer; - } - - entry.push_back(Pair("#" + ToString(++i) + " [" + RoundToString(participants,3) + "]. " + answer,dShares)); - total_participants += participants; - total_shares += dShares; - sExportRow += "" + answer + "" + RoundToString(participants,0) + "" + RoundToString(dShares,0) + ""; + highest_share = dShares; + BestAnswer = answer; } - sExportRow += ""; - //Totals: - entry.push_back(Pair("Participants",total_participants)); - entry.push_back(Pair("Total Shares",total_shares)); - if (total_participants < 3) BestAnswer = ""; + entry.push_back(Pair("#" + ToString(++i) + " [" + RoundToString(participants,3) + "]. " + answer,dShares)); + total_participants += participants; + total_shares += dShares; + sExportRow += "" + answer + "" + RoundToString(participants,0) + "" + RoundToString(dShares,0) + ""; + } + sExportRow += ""; - entry.push_back(Pair("Best Answer",BestAnswer)); - sExportRow += "" + RoundToString(total_participants,0) - + "" + RoundToString(total_shares,0) - + "" + BestAnswer + ""; + //Totals: + entry.push_back(Pair("Participants",total_participants)); + entry.push_back(Pair("Total Shares",total_shares)); + if (total_participants < 3) BestAnswer = ""; + + entry.push_back(Pair("Best Answer",BestAnswer)); + sExportRow += "" + RoundToString(total_participants,0) + + "" + RoundToString(total_shares,0) + + "" + BestAnswer + ""; - } - sExportRow += ""; - sExport += sExportRow; } + sExportRow += ""; + sExport += sExportRow; } } } @@ -3596,38 +3564,33 @@ Array GetJSONPollsReport(bool bDetail, std::string QueryByTitle, std::string& ou Array GetUpgradedBeaconReport() { - Array results; - Object entry; - entry.push_back(Pair("Report","Upgraded Beacon Report 1.0")); - std::string datatype="beacon"; - std::string rows = ""; - std::string row = ""; - int iBeaconCount = 0; - int iUpgradedBeaconCount = 0; - for(map::iterator ii=mvApplicationCache.begin(); ii!=mvApplicationCache.end(); ++ii) - { - std::string key_name = (*ii).first; - if (key_name.length() > datatype.length()) - { - if (key_name.substr(0,datatype.length())==datatype) - { - std::string key_value = mvApplicationCache[(*ii).first]; - std::string subkey = key_name.substr(datatype.length()+1,key_name.length()-datatype.length()-1); - std::string contract = DecodeBase64(key_value); - std::string cpidv2 = ExtractValue(contract,";",0); - std::string grcaddress = ExtractValue(contract,";",2); - std::string sPublicKey = ExtractValue(contract,";",3); - if (!sPublicKey.empty()) iUpgradedBeaconCount++; - iBeaconCount++; - } - } - } - entry.push_back(Pair("Total Beacons",(double)iBeaconCount)); - entry.push_back(Pair("Upgraded Beacon Count",(double)iUpgradedBeaconCount)); - double dPct = ((double)iUpgradedBeaconCount / ((double)iBeaconCount) + .01); - entry.push_back(Pair("Pct Of Upgraded Beacons",RoundToString(dPct*100,3))); - results.push_back(entry); - return results; + Array results; + Object entry; + entry.push_back(Pair("Report","Upgraded Beacon Report 1.0")); + std::string datatype="beacon"; + std::string rows = ""; + std::string row = ""; + int iBeaconCount = 0; + int iUpgradedBeaconCount = 0; + for(const auto& item : AppCacheIterator(datatype)) + { + const std::string& key_name = item.first; + const std::string& key_value = item.second; + std::string subkey = key_name.substr(datatype.length()+1,key_name.length()-datatype.length()-1); + std::string contract = DecodeBase64(key_value); + std::string cpidv2 = ExtractValue(contract,";",0); + std::string grcaddress = ExtractValue(contract,";",2); + std::string sPublicKey = ExtractValue(contract,";",3); + if (!sPublicKey.empty()) iUpgradedBeaconCount++; + iBeaconCount++; + } + + entry.push_back(Pair("Total Beacons",(double)iBeaconCount)); + entry.push_back(Pair("Upgraded Beacon Count",(double)iUpgradedBeaconCount)); + double dPct = ((double)iUpgradedBeaconCount / ((double)iBeaconCount) + .01); + entry.push_back(Pair("Pct Of Upgraded Beacons",RoundToString(dPct*100,3))); + results.push_back(entry); + return results; } @@ -3636,33 +3599,26 @@ Array GetUpgradedBeaconReport() Array GetJSONBeaconReport() { - Array results; - Object entry; - entry.push_back(Pair("CPID","GRCAddress")); - std::string datatype="beacon"; - std::string row = ""; - for(map::iterator ii=mvApplicationCache.begin(); ii!=mvApplicationCache.end(); ++ii) - { - std::string key_name = (*ii).first; - if (key_name.length() > datatype.length()) - { - if (key_name.substr(0,datatype.length())==datatype) - { - std::string key_value = mvApplicationCache[(*ii).first]; - std::string subkey = key_name.substr(datatype.length()+1,key_name.length()-datatype.length()-1); - row = subkey + "" + key_value; - // std::string contract = GlobalCPUMiningCPID.cpidv2 + ";" + hashRand.GetHex() + ";" + GRCAddress; - std::string contract = DecodeBase64(key_value); - std::string cpid = subkey; - std::string cpidv2 = ExtractValue(contract,";",0); - std::string grcaddress = ExtractValue(contract,";",2); - entry.push_back(Pair(cpid,grcaddress)); - } - } - } - - results.push_back(entry); - return results; + Array results; + Object entry; + entry.push_back(Pair("CPID","GRCAddress")); + std::string datatype="beacon"; + std::string row; + for(const auto& item : AppCacheIterator(datatype)) + { + const std::string& key_name = item.first; + const std::string& key_value = item.second; + std::string subkey = key_name.substr(datatype.length()+1,key_name.length()-datatype.length()-1); + row = subkey + "" + key_value; + // std::string contract = GlobalCPUMiningCPID.cpidv2 + ";" + hashRand.GetHex() + ";" + GRCAddress; + std::string contract = DecodeBase64(key_value); + std::string cpid = subkey; + std::string grcaddress = ExtractValue(contract,";",2); + entry.push_back(Pair(cpid,grcaddress)); + } + + results.push_back(entry); + return results; } From 44a03c8738e88aaf0d800357d773a8d3865379d9 Mon Sep 17 00:00:00 2001 From: skcin Date: Mon, 25 Sep 2017 17:54:06 +0200 Subject: [PATCH 006/166] Introduce a new class to manage threads in a thread group --- src/init.cpp | 16 +++++++------- src/init.h | 6 +++-- src/qt/bitcoin.cpp | 29 ++++++++++++++++++++---- src/qt/bitcoingui.cpp | 29 ++++++++++++++++-------- src/qt/bitcoingui.h | 5 +++++ src/util.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++ src/util.h | 16 ++++++++++++++ 7 files changed, 129 insertions(+), 23 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 65671f2c01..4621a60fc7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -29,7 +29,6 @@ extern boost::thread_group threadGroup; StructCPID GetStructCPID(); bool ComputeNeuralNetworkSupermajorityHashes(); void BusyWaitForTally(); -extern void ThreadAppInit2(void* parg); void LoadCPIDsInBackground(); bool IsConfigFileEmpty(); @@ -161,7 +160,7 @@ void InitializeBoincProjects() } -void Shutdown(void* parg) +void Shutdown(void* parg,boost::shared_ptr threads) { static CCriticalSection cs_Shutdown; static bool fTaken; @@ -192,7 +191,7 @@ void Shutdown(void* parg) boost::filesystem::remove(GetPidFile()); UnregisterWallet(pwalletMain); delete pwalletMain; - NewThread(ExitTimeout, NULL); + threads->createThread(ExitTimeout, NULL, "Exit Timeout Thread"); MilliSleep(50); printf("Gridcoin exited\n\n"); fExit = true; @@ -446,13 +445,13 @@ bool InitSanityCheck(void) -void ThreadAppInit2(void* parg) +void ThreadAppInit2(boost::shared_ptr th) { // Make this thread recognisable RenameThread("grc-appinit2"); bGridcoinGUILoaded=false; printf("Initializing GUI..."); - AppInit2(); + AppInit2(th); printf("GUI Loaded..."); bGridcoinGUILoaded = true; } @@ -464,7 +463,7 @@ void ThreadAppInit2(void* parg) /** Initialize Gridcoin. * @pre Parameters should be parsed and config file should be read. */ -bool AppInit2() +bool AppInit2(boost::shared_ptr threads) { // ********************************************************* Step 1: setup #ifdef _MSC_VER @@ -1108,12 +1107,13 @@ bool AppInit2() uiInterface.InitMessage(_("Loading Network Averages...")); if (fDebug3) printf("Loading network averages"); - if (!NewThread(StartNode, NULL)) + if (!threads->createThread(StartNode, NULL, "Start Thread")) + InitError(_("Error: could not start node")); BusyWaitForTally(); if (fServer) - NewThread(ThreadRPCServer, NULL); + threads->createThread(ThreadRPCServer, NULL, "RPC Server Thread"); // ********************************************************* Step 12: finished diff --git a/src/init.h b/src/init.h index ec3d7ac46f..5d03936f79 100644 --- a/src/init.h +++ b/src/init.h @@ -13,8 +13,10 @@ void StartShutdown(); bool ShutdownRequested(); -void Shutdown(void* parg); -bool AppInit2(); +void Shutdown(void* parg, boost::shared_ptr threads); +bool AppInit2(boost::shared_ptr threads); +void ThreadAppInit2(boost::shared_ptr th); + std::string HelpMessage(); std::string LogSomething(); diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 0776e01c14..754268b799 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -12,6 +12,7 @@ #include "walletmodel.h" #include "optionsmodel.h" #include "guiutil.h" +#include "util.h" #include "guiconstants.h" #include "init.h" #include "ui_interface.h" @@ -22,6 +23,7 @@ #include #include #include +#include #if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) #define _BITCOIN_QT_PLUGINS_INCLUDED @@ -38,7 +40,6 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets) static BitcoinGUI *guiref; static QSplashScreen *splashref; -void ThreadAppInit2(void* parg); boost::thread_group threadGroup; //Global reference to globalcom @@ -149,6 +150,11 @@ static void handleRunawayException(std::exception *e) #ifndef BITCOIN_QT_TEST int main(int argc, char *argv[]) { + // Set default value to exit properly. Exit code 42 will trigger restart of the wallet. + int currentExitCode = 0; + + boost::shared_ptr threads(new ThreadHandler); + // Do this early as we don't want to bother initializing if we are just calling IPC ipcScanRelay(argc, argv); @@ -268,7 +274,7 @@ int main(int argc, char *argv[]) QObject::connect(timer, SIGNAL(timeout()), guiref, SLOT(timerfire())); //Start globalcom - if (!NewThread(ThreadAppInit2, NULL)) + if (!threads->createThread(ThreadAppInit2,threads,"AppInit2 Thread")) { printf("Error; NewThread(ThreadAppInit2) failed\n"); return 1; @@ -309,7 +315,7 @@ int main(int argc, char *argv[]) // Place this here as guiref has to be defined if we don't want to lose URIs ipcInit(argc, argv); - app.exec(); + currentExitCode = app.exec(); window.hide(); window.setClientModel(0); @@ -318,7 +324,7 @@ int main(int argc, char *argv[]) } // Shutdown the core and its threads, but don't exit Bitcoin-Qt here printf("\r\nbitcoin.cpp:main calling Shutdown...\r\n"); - Shutdown(NULL); + Shutdown(NULL,threads); } } @@ -330,6 +336,21 @@ int main(int argc, char *argv[]) { handleRunawayException(NULL); } + + // delete thread handler + threads->removeAll(); + printf("Amount of threads left: %d",threads->numThreads()); + threads.reset(); + + // use exit codes to trigger restart of the wallet + if(currentExitCode == EXIT_CODE_REBOOT) + { + sleep(180); + QStringList args = QApplication::arguments(); + args.removeFirst(); + QProcess::startDetached(QApplication::applicationFilePath(), args); + } + return 0; } #endif // BITCOIN_QT_TEST diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 0f69a12050..0d3c64d6da 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -728,17 +728,21 @@ void BitcoinGUI::createActions() rebuildAction->setStatusTip(tr("Rebuild Block Chain")); rebuildAction->setMenuRole(QAction::TextHeuristicRole); - downloadAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Download Blocks"), this); - downloadAction->setStatusTip(tr("Download Blocks")); - downloadAction->setMenuRole(QAction::TextHeuristicRole); + downloadAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Download Blocks"), this); + downloadAction->setStatusTip(tr("Download Blocks")); + downloadAction->setMenuRole(QAction::TextHeuristicRole); - upgradeAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Upgrade Client"), this); - upgradeAction->setStatusTip(tr("Upgrade Client")); - upgradeAction->setMenuRole(QAction::TextHeuristicRole); + upgradeAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Upgrade Client"), this); + upgradeAction->setStatusTip(tr("Upgrade Client")); + upgradeAction->setMenuRole(QAction::TextHeuristicRole); - aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About Gridcoin"), this); - aboutAction->setToolTip(tr("Show information about Gridcoin")); - aboutAction->setMenuRole(QAction::AboutRole); + rebootAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Reboot Client"), this); + rebootAction->setStatusTip(tr("Reboote Client")); + rebootAction->setMenuRole(QAction::TextHeuristicRole); + + aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About Gridcoin"), this); + aboutAction->setToolTip(tr("Show information about Gridcoin")); + aboutAction->setMenuRole(QAction::AboutRole); miningAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Neural Network"), this); miningAction->setStatusTip(tr("Neural Network")); @@ -802,6 +806,7 @@ void BitcoinGUI::createActions() connect(rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildClicked())); connect(upgradeAction, SIGNAL(triggered()), this, SLOT(upgradeClicked())); connect(downloadAction, SIGNAL(triggered()), this, SLOT(downloadClicked())); + connect(rebootAction, SIGNAL (triggered()),this, SLOT (rebootClicked())); connect(configAction, SIGNAL(triggered()), this, SLOT(configClicked())); connect(miningAction, SIGNAL(triggered()), this, SLOT(miningClicked())); @@ -864,6 +869,7 @@ void BitcoinGUI::createMenuBar() qmAdvanced->addSeparator(); qmAdvanced->addAction(rebuildAction); qmAdvanced->addAction(downloadAction); + qmAdvanced->addAction(rebootAction); QMenu *help = appMenuBar->addMenu(tr("&Help")); help->addAction(openRPCConsoleAction); @@ -1446,6 +1452,11 @@ void BitcoinGUI::downloadClicked() DownloadBlocks(); } +void BitcoinGUI::rebootClicked() +{ + qApp->exit(EXIT_CODE_REBOOT); +} + void BitcoinGUI::configClicked() { #ifdef WIN32 diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 4b0b7253b2..28eae72a8f 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -12,6 +12,8 @@ #include #endif +// exit code used to trigger a restart of the wallet +#define EXIT_CODE_REBOOT 42 class TransactionTableModel; class ClientModel; @@ -106,6 +108,7 @@ class BitcoinGUI : public QMainWindow QAction *rebuildAction; QAction *upgradeAction; QAction *downloadAction; + QAction *rebootAction; QAction *configAction; QAction *leaderboardAction; @@ -225,6 +228,8 @@ private slots: void newUserWizardClicked(); + void rebootClicked(); + #ifndef Q_OS_MAC /** Handle tray icon clicked */ diff --git a/src/util.cpp b/src/util.cpp index 622a464ba1..6f33c8f44f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1583,3 +1583,54 @@ std::string MakeSafeMessage(const std::string& messagestring) } return safemessage; } + +bool ThreadHandler::createThread(void(*pfn)(boost::shared_ptr), boost::shared_ptr parg, const std::string tname) +{ + try + { + boost::thread *newThread = new boost::thread(pfn, parg); + threadGroup.add_thread(newThread); + threadMap[tname] = newThread; + } catch(boost::thread_resource_error &e) { + printf("Error creating thread: %s\n", e.what()); + return false; + } + return true; +} + +bool ThreadHandler::createThread(void(*pfn)(void*), void* parg, const std::string tname) +{ + try + { + boost::thread *newThread = new boost::thread(pfn, parg); + threadGroup.add_thread(newThread); + threadMap[tname] = newThread; + } catch(boost::thread_resource_error &e) { + printf("Error creating thread: %s\n", e.what()); + return false; + } + return true; +} + +int ThreadHandler::numThreads() +{ + return threadGroup.size(); +} + +void ThreadHandler::removeByName(const std::string tName) +{ + threadGroup.remove_thread(threadMap[tName]); + threadMap[tName]->join(); + threadMap.erase(tName); +} + +void ThreadHandler::removeAll() +{ + printf("Wait for %d threads to join.\n",numThreads()); + threadGroup.join_all(); + for (auto it=threadMap.begin(); it!=threadMap.end(); ++it) + { + threadGroup.remove_thread(it->second); + } + threadMap.clear(); +} diff --git a/src/util.h b/src/util.h index 7c90f5d2f3..735e97ddd1 100644 --- a/src/util.h +++ b/src/util.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -621,5 +622,20 @@ template class CMedianFilter bool NewThread(void(*pfn)(void*), void* parg); void RenameThread(const char* name); +class ThreadHandler +{ +public: + ThreadHandler(){}; + ~ThreadHandler(){}; + bool createThread(void(*pfn)(boost::shared_ptr), boost::shared_ptr parg, const std::string tname); + bool createThread(void(*pfn)(void*), void* parg, const std::string tname); + int numThreads(); + void removeAll(); + void removeByName(const std::string tName); +private: + boost::thread_group threadGroup; + std::map threadMap; +}; + #endif From 357a93bea31c619e6b25a69f3cce0921c08f02c8 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 26 Sep 2017 15:05:52 +0200 Subject: [PATCH 007/166] Reduce the number of blocks sent per batch and stop rewinding to PoW blocks. --- src/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b9dd6b4a92..e07ed90ff8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6611,11 +6611,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Trigger them to send a getblocks request for the next batch of inventory if (inv.hash == pfrom->hashContinue) { - // ppcoin: send latest proof-of-work block to allow the - // download node to accept as orphan (proof-of-stake - // block might be rejected by stake connection check) + // Bypass PushInventory, this must send even if redundant, + // and we want it right after the last block so they don't + // wait for other stuff first. vector vInv; - vInv.push_back(CInv(MSG_BLOCK, GetLastBlockIndex(pindexBest, false)->GetBlockHash())); + vInv.push_back(CInv(MSG_BLOCK, hashBestChain)); pfrom->PushMessage("inv", vInv); pfrom->hashContinue = 0; } @@ -6661,7 +6661,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Send the rest of the chain if (pindex) pindex = pindex->pnext; - int nLimit = 1000; + int nLimit = 500; if (fDebug3) printf("\r\ngetblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit); for (; pindex; pindex = pindex->pnext) From 4a59c4e6bf537085dd037082beb4c4e274084705 Mon Sep 17 00:00:00 2001 From: skcin Date: Wed, 27 Sep 2017 14:14:51 +0200 Subject: [PATCH 008/166] Move all the networking threads to an instance of the new thread handler, managing them in a boost thread_group. The threads exit if fShutdown is true or they are interrupted. On shutdown interrupt is called on all threads managed by the thread handler. The program waits until all of them are joined properly. --- src/bitcoinrpc.cpp | 28 ++-- src/irc.cpp | 14 +- src/net.cpp | 309 ++++++++++++++++++++++----------------------- src/net.h | 23 +--- src/qt/bitcoin.cpp | 2 +- src/util.cpp | 20 ++- src/util.h | 4 +- 7 files changed, 194 insertions(+), 206 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 7590f3121a..121ed1b830 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -671,15 +671,19 @@ void ThreadRPCServer(void* parg) try { - vnThreadsRunning[THREAD_RPCLISTENER]++; ThreadRPCServer2(parg); - vnThreadsRunning[THREAD_RPCLISTENER]--; } - catch (std::exception& e) { - vnThreadsRunning[THREAD_RPCLISTENER]--; + catch (std::exception& e) + { PrintException(&e, "ThreadRPCServer()"); - } catch (...) { - vnThreadsRunning[THREAD_RPCLISTENER]--; + } + catch (boost::thread_interrupted&) + { + printf("ThreadRPCServer exited (interrupt)\r\n"); + return; + } + catch (...) + { PrintException(NULL, "ThreadRPCServer()"); } printf("ThreadRPCServer exited\n"); @@ -725,7 +729,6 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptorcreateThread(ThreadRPCServer3, conn,"ThreadRPCServer3")) { + printf("Failed to create RPC server client thread\r\n"); delete conn; } - - vnThreadsRunning[THREAD_RPCLISTENER]--; } void ThreadRPCServer2(void* parg) @@ -885,10 +886,8 @@ void ThreadRPCServer2(void* parg) return; } - vnThreadsRunning[THREAD_RPCLISTENER]--; while (!fShutdown) io_service.run_one(); - vnThreadsRunning[THREAD_RPCLISTENER]++; StopRequests(); } @@ -978,7 +977,6 @@ void ThreadRPCServer3(void* parg) { LOCK(cs_THREAD_RPCHANDLER); - vnThreadsRunning[THREAD_RPCHANDLER]++; } AcceptedConnection *conn = (AcceptedConnection *) parg; @@ -991,7 +989,6 @@ void ThreadRPCServer3(void* parg) delete conn; { LOCK(cs_THREAD_RPCHANDLER); - --vnThreadsRunning[THREAD_RPCHANDLER]; } return; } @@ -1063,7 +1060,6 @@ void ThreadRPCServer3(void* parg) delete conn; { LOCK(cs_THREAD_RPCHANDLER); - vnThreadsRunning[THREAD_RPCHANDLER]--; } } diff --git a/src/irc.cpp b/src/irc.cpp index 6861594483..6395f827b2 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -195,12 +195,20 @@ void ThreadIRCSeed(void* parg) { ThreadIRCSeed2(parg); } - catch (std::exception& e) { + catch (std::exception& e) + { PrintExceptionContinue(&e, "ThreadIRCSeed()"); - } catch (...) { + } + catch(boost::thread_interrupted&) + { + printf("ThreadIRCSeed exited (interrupt)\r\n"); + return; + } + catch (...) + { PrintExceptionContinue(NULL, "ThreadIRCSeed()"); } - if (fDebug) printf("ThreadIRCSeed exited\n"); + printf("ThreadIRCSeed exited\r\n"); } void ThreadIRCSeed2(void* parg) diff --git a/src/net.cpp b/src/net.cpp index 964ad19786..13c9847cbf 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -33,9 +33,6 @@ extern void ExecGridcoinServices(void* parg); std::string DefaultWalletAddress(); std::string NodeAddress(CNode* pfrom); -#ifndef QT_GUI - boost::thread_group threadGroup; -#endif extern std::string GetCommandNonce(std::string command); extern std::string DefaultOrg(); extern std::string DefaultOrgKey(int key_length); @@ -79,7 +76,8 @@ static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; CAddress addrSeenByPeer(CService("0.0.0.0", 0), nLocalServices); uint64_t nLocalHostNonce = 0; -std::array vnThreadsRunning; + +ThreadHandler* netThreads = new ThreadHandler; static std::vector vhListenSocket; CAddrMan addrman; @@ -543,12 +541,26 @@ void ThreadGetMyExternalIP(void* parg) { // Make this thread recognisable as the external IP detection thread RenameThread("grc-ext-ip"); - - CNetAddr addrLocalHost; - if (GetMyExternalIP(addrLocalHost)) + try + { + CNetAddr addrLocalHost; + if (GetMyExternalIP(addrLocalHost)) + { + printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str()); + AddLocal(addrLocalHost, LOCAL_HTTP); + } + } + catch (std::exception& e) + { + PrintException(&e, "ThreadMyExternalIP()"); + } + catch(boost::thread_interrupted&) + { + return; + } + catch (...) { - printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str()); - AddLocal(addrLocalHost, LOCAL_HTTP); + PrintException(NULL, "ThreadGetMyExternalIP()"); } } @@ -963,18 +975,22 @@ void ThreadSocketHandler(void* parg) try { - vnThreadsRunning[THREAD_SOCKETHANDLER]++; ThreadSocketHandler2(parg); - vnThreadsRunning[THREAD_SOCKETHANDLER]--; } - catch (std::exception& e) { - vnThreadsRunning[THREAD_SOCKETHANDLER]--; + catch (std::exception& e) + { PrintException(&e, "ThreadSocketHandler()"); - } catch (...) { - vnThreadsRunning[THREAD_SOCKETHANDLER]--; + } + catch(boost::thread_interrupted&) + { + printf("ThreadSocketHandler exited (interrupt)\r\n"); + return; + } + catch (...) + { throw; // support pthread_cancel() } - printf("ThreadSocketHandler exited\n"); + printf("ThreadSocketHandler exited\r\n"); } void ThreadSocketHandler2(void* parg) @@ -1103,10 +1119,8 @@ void ThreadSocketHandler2(void* parg) } } - vnThreadsRunning[THREAD_SOCKETHANDLER]--; int nSelect = select(have_fds ? hSocketMax + 1 : 0, &fdsetRecv, &fdsetSend, &fdsetError, &timeout); - vnThreadsRunning[THREAD_SOCKETHANDLER]++; if (fShutdown) return; if (nSelect == SOCKET_ERROR) @@ -1312,14 +1326,6 @@ void ThreadSocketHandler2(void* parg) } } - - - - - - - - #ifdef USE_UPNP void ThreadMapPort(void* parg) { @@ -1328,18 +1334,21 @@ void ThreadMapPort(void* parg) try { - vnThreadsRunning[THREAD_UPNP]++; ThreadMapPort2(parg); - vnThreadsRunning[THREAD_UPNP]--; } catch (std::exception& e) { - vnThreadsRunning[THREAD_UPNP]--; PrintException(&e, "ThreadMapPort()"); - } catch (...) { - vnThreadsRunning[THREAD_UPNP]--; + } + catch(boost::thread_interrupted&) + { + printf("ThreadMapPort exited (interrupt)\r\n"); + return; + } + catch (...) + { PrintException(NULL, "ThreadMapPort()"); } - printf("ThreadMapPort exited\n"); + printf("ThreadMapPort exited\r\n"); } void ThreadMapPort2(void* parg) @@ -1385,7 +1394,7 @@ void ThreadMapPort2(void* parg) AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP); } else - printf("UPnP: GetExternalIPAddress not successful.\n"); + printf("UPnP: GetExternalIPAddress not successful.\r\n"); } } @@ -1453,10 +1462,10 @@ void ThreadMapPort2(void* parg) void MapPort() { - if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1) + if (fUseUPnP && !netThreads->threadExists("ThreadMapPort")) { - if (!NewThread(ThreadMapPort, NULL)) - printf("Error: ThreadMapPort(ThreadMapPort) did not succeed\n"); + if (!netThreads->createThread(ThreadMapPort,NULL,"ThreadMapPort")) + printf("Error: createThread(ThreadMapPort) failed\r\n"); } } #else @@ -1466,14 +1475,6 @@ void MapPort() } #endif - - - - - - - - // DNS seeds // Each pair gives a source name and a seed name. // The first name is used as information source for addrman. @@ -1494,18 +1495,22 @@ void ThreadDNSAddressSeed(void* parg) try { - vnThreadsRunning[THREAD_DNSSEED]++; ThreadDNSAddressSeed2(parg); - vnThreadsRunning[THREAD_DNSSEED]--; } - catch (std::exception& e) { - vnThreadsRunning[THREAD_DNSSEED]--; + catch (std::exception& e) + { PrintException(&e, "ThreadDNSAddressSeed()"); - } catch (...) { - vnThreadsRunning[THREAD_DNSSEED]--; + } + catch(boost::thread_interrupted&) + { + if (fDebug10) printf("ThreadDNSAddressSeed exited (interrupt)\r\n"); + return; + } + catch (...) + { throw; // support pthread_cancel() } - if (fDebug10) printf("ThreadDNSAddressSeed exited\n"); + if (fDebug10) printf("ThreadDNSAddressSeed exited\r\n"); } void ThreadDNSAddressSeed2(void* parg) @@ -1585,14 +1590,19 @@ void ThreadTallyResearchAverages(void* parg) { PrintException(&e, "ThreadTallyNetworkAverages()"); } + catch(boost::thread_interrupted&) + { + printf("ThreadTallyResearchAverages exited (interrupt)\r\n"); + return; + } catch(...) { - printf("Error in ThreadTallyResearchAverages... Recovering "); + printf("Error in ThreadTallyResearchAverages... Recovering \r\n"); } MilliSleep(10000); if (!fShutdown) printf("Thread TallyReasearchAverages exited, Restarting.. \r\n"); if (!fShutdown) goto begin; - + printf("ThreadTallyResearchAverages exited \r\n"); } @@ -1615,6 +1625,11 @@ void ThreadExecuteGridcoinServices(void* parg) { PrintException(&e, "ThreadExecuteGridcoinServices()"); } + catch(boost::thread_interrupted&) + { + printf("ThreadExecuteGridcoinServices exited (interrupt)\r\n"); + return; + } catch(...) { printf("Error in ThreadExecuteGridcoinServices... Recovering "); @@ -1648,7 +1663,6 @@ void BusyWaitForTally() void DoTallyResearchAverages(void* parg) { - vnThreadsRunning[THREAD_TALLY]++; printf("\r\nStarting dedicated Tally thread...\r\n"); while (!fShutdown) @@ -1675,13 +1689,11 @@ void DoTallyResearchAverages(void* parg) bTallyFinished = true; } } - vnThreadsRunning[THREAD_TALLY]--; } void ExecGridcoinServices(void* parg) { - vnThreadsRunning[THREAD_SERVICES]++; printf("\r\nStarting dedicated Gridcoin Services thread...\r\n"); while (!fShutdown) @@ -1692,7 +1704,6 @@ void ExecGridcoinServices(void* parg) bExecuteGridcoinServices=false; } } - vnThreadsRunning[THREAD_SERVICES]--; } @@ -1700,15 +1711,11 @@ void ExecGridcoinServices(void* parg) void ThreadDumpAddress2(void* parg) { - vnThreadsRunning[THREAD_DUMPADDRESS]++; while (!fShutdown) { DumpAddresses(); - vnThreadsRunning[THREAD_DUMPADDRESS]--; MilliSleep(600000); - vnThreadsRunning[THREAD_DUMPADDRESS]++; } - vnThreadsRunning[THREAD_DUMPADDRESS]--; } void ThreadDumpAddress(void* parg) @@ -1720,10 +1727,20 @@ void ThreadDumpAddress(void* parg) { ThreadDumpAddress2(parg); } - catch (std::exception& e) { + catch (std::exception& e) + { PrintException(&e, "ThreadDumpAddress()"); } - printf("ThreadDumpAddress exited\n"); + catch(boost::thread_interrupted&) + { + printf("ThreadDumpAddress exited (interrupt)\r\n"); + return; + } + catch (...) + { + PrintException(NULL, "ThreadDumpAddress"); + } + printf("ThreadDumpAddress exited\r\n"); } void ThreadOpenConnections(void* parg) @@ -1733,18 +1750,22 @@ void ThreadOpenConnections(void* parg) try { - vnThreadsRunning[THREAD_OPENCONNECTIONS]++; ThreadOpenConnections2(parg); - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; } - catch (std::exception& e) { - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + catch (std::exception& e) + { PrintException(&e, "ThreadOpenConnections()"); - } catch (...) { - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; + } + catch(boost::thread_interrupted&) + { + printf("ThreadOpenConnections exited (interrupt)\r\n"); + return; + } + catch (...) + { PrintException(NULL, "ThreadOpenConnections()"); } - printf("ThreadOpenConnections exited\n"); + printf("ThreadOpenConnections exited\r\n"); } void static ProcessOneShot() @@ -1776,18 +1797,22 @@ void static ThreadStakeMiner(void* parg) } try { - vnThreadsRunning[THREAD_STAKE_MINER]++; StakeMiner(pwallet); - vnThreadsRunning[THREAD_STAKE_MINER]--; } - catch (std::exception& e) { - vnThreadsRunning[THREAD_STAKE_MINER]--; + catch (std::exception& e) + { PrintException(&e, "ThreadStakeMiner()"); - } catch (...) { - vnThreadsRunning[THREAD_STAKE_MINER]--; + } + catch(boost::thread_interrupted&) + { + printf("ThreadStakeMiner exited (interrupt)\r\n"); + return; + } + catch (...) + { PrintException(NULL, "ThreadStakeMiner()"); } - printf("ThreadStakeMiner exiting, %d threads remaining\n", vnThreadsRunning[THREAD_STAKE_MINER]); + printf("ThreadStakeMiner exited\r\n"); } @@ -1842,16 +1867,12 @@ void ThreadOpenConnections2(void* parg) while (true) { ProcessOneShot(); - - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; MilliSleep(500); - vnThreadsRunning[THREAD_OPENCONNECTIONS]++; + if (fShutdown) return; - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; CSemaphoreGrant grant(*semOutbound); - vnThreadsRunning[THREAD_OPENCONNECTIONS]++; if (fShutdown) return; @@ -1940,18 +1961,22 @@ void ThreadOpenAddedConnections(void* parg) try { - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; ThreadOpenAddedConnections2(parg); - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; } - catch (std::exception& e) { - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + catch (std::exception& e) + { PrintException(&e, "ThreadOpenAddedConnections()"); - } catch (...) { - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; + } + catch(boost::thread_interrupted&) + { + printf("ThreadOpenAddedConnections exited (interrupt)\r\n"); + return; + } + catch (...) + { PrintException(NULL, "ThreadOpenAddedConnections()"); } - printf("ThreadOpenAddedConnections exited\n"); + printf("ThreadOpenAddedConnections exited\r\n"); } void ThreadOpenAddedConnections2(void* parg) @@ -1969,9 +1994,7 @@ void ThreadOpenAddedConnections2(void* parg) OpenNetworkConnection(addr, &grant, strAddNode.c_str()); MilliSleep(500); } - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; MilliSleep(120000); // Retry every 2 minutes - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; } return; } @@ -2017,9 +2040,7 @@ void ThreadOpenAddedConnections2(void* parg) } if (fShutdown) return; - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--; MilliSleep(120000); // Retry every 2 minutes - vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++; if (fShutdown) return; } @@ -2041,9 +2062,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu if (strDest && FindNode(strDest)) return false; - vnThreadsRunning[THREAD_OPENCONNECTIONS]--; CNode* pnode = ConnectNode(addrConnect, strDest); - vnThreadsRunning[THREAD_OPENCONNECTIONS]++; if (fShutdown) return false; if (!pnode) @@ -2057,9 +2076,6 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu return true; } - - - void ThreadMessageHandler(void* parg) { // Make this thread recognisable as the message handling thread @@ -2067,18 +2083,22 @@ void ThreadMessageHandler(void* parg) try { - vnThreadsRunning[THREAD_MESSAGEHANDLER]++; ThreadMessageHandler2(parg); - vnThreadsRunning[THREAD_MESSAGEHANDLER]--; } - catch (std::exception& e) { - vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + catch (std::exception& e) + { PrintException(&e, "ThreadMessageHandler()"); - } catch (...) { - vnThreadsRunning[THREAD_MESSAGEHANDLER]--; + } + catch(boost::thread_interrupted&) + { + printf("ThreadMessageHandler exited (interrupt)\r\n"); + return; + } + catch (...) + { PrintException(NULL, "ThreadMessageHandler()"); } - printf("ThreadMessageHandler exited\n"); + printf("ThreadMessageHandler exited\r\n"); } void ThreadMessageHandler2(void* parg) @@ -2131,13 +2151,10 @@ void ThreadMessageHandler2(void* parg) } // Wait and allow messages to bunch up. - // Reduce vnThreadsRunning so StopNode has permission to exit while // we're sleeping, but we must always check fShutdown after doing this. - vnThreadsRunning[THREAD_MESSAGEHANDLER]--; MilliSleep(100); if (fRequestShutdown) StartShutdown(); - vnThreadsRunning[THREAD_MESSAGEHANDLER]++; if (fShutdown) return; } @@ -2302,7 +2319,7 @@ void static Discover() // Don't use external IPv4 discovery, when -onlynet="IPv6" if (!IsLimited(NET_IPV4)) - NewThread(ThreadGetMyExternalIP, NULL); + netThreads->createThread(ThreadGetMyExternalIP, NULL,"ThreadGetMyExternalIP"); } void StartNode(void* parg) @@ -2330,53 +2347,53 @@ void StartNode(void* parg) // if (!GetBoolArg("-dnsseed", true)) - printf("DNS seeding disabled\n"); + printf("DNS seeding disabled\r\n"); else - if (!NewThread(ThreadDNSAddressSeed, NULL)) - printf("Error: NewThread(ThreadDNSAddressSeed) failed\n"); + if (!netThreads->createThread(ThreadDNSAddressSeed,NULL,"ThreadDNSAddressSeed")) + printf("Error: createThread(ThreadDNSAddressSeed) failed\r\n"); // Map ports with UPnP if (fUseUPnP) MapPort(); // Get addresses from IRC and advertise ours - if (!NewThread(ThreadIRCSeed, NULL)) - printf("Error: NewThread(ThreadIRCSeed) failed\n"); + if (!netThreads->createThread(ThreadIRCSeed,NULL,"ThreadIRCSeed")) + printf("Error: createThread(ThreadIRCSeed) failed\r\n"); // Send and receive from sockets, accept connections - if (!NewThread(ThreadSocketHandler, NULL)) - printf("Error: NewThread(ThreadSocketHandler) failed\n"); + if (!netThreads->createThread(ThreadSocketHandler,NULL,"ThreadSocketHandler")) + printf("Error: createThread(ThreadSocketHandler) failed\r\n"); // Initiate outbound connections from -addnode - if (!NewThread(ThreadOpenAddedConnections, NULL)) - printf("Error: NewThread(ThreadOpenAddedConnections) failed\n"); + if (!netThreads->createThread(ThreadOpenAddedConnections,NULL,"ThreadOpenAddedConnections")) + printf("Error: createThread(ThreadOpenAddedConnections) failed\r\n"); // Initiate outbound connections - if (!NewThread(ThreadOpenConnections, NULL)) - printf("Error: NewThread(ThreadOpenConnections) failed\n"); + if (!netThreads->createThread(ThreadOpenConnections,NULL,"ThreadOpenConnections")) + printf("Error: createThread(ThreadOpenConnections) failed\r\n"); // Process messages - if (!NewThread(ThreadMessageHandler, NULL)) - printf("Error: NewThread(ThreadMessageHandler) failed\n"); + if (!netThreads->createThread(ThreadMessageHandler,NULL,"ThreadMessageHandler")) + printf("Error: createThread(ThreadMessageHandler) failed\n"); // Dump network addresses - if (!NewThread(ThreadDumpAddress, NULL)) - printf("Error; NewThread(ThreadDumpAddress) failed\n"); + if (!netThreads->createThread(ThreadDumpAddress,NULL,"ThreadDumpAddress")) + printf("Error: createThread(ThreadDumpAddress) failed\r\n"); // Tally network averages - if (!NewThread(ThreadTallyResearchAverages, NULL)) - printf("Error; NewThread(ThreadTally) failed\n"); + if (!netThreads->createThread(ThreadTallyResearchAverages,NULL,"ThreadTallyResearchAverages")) + printf("Error: createThread(ThreadTally) failed\r\n"); // Services - if (!NewThread(ThreadExecuteGridcoinServices, NULL)) - printf("Error; NewThread(ThreadExecuteGridcoinServices) failed\r\n"); + if (!netThreads->createThread(ThreadExecuteGridcoinServices,NULL,"ThreadExecuteGridcoinServices")) + printf("Error: createThread(ThreadExecuteGridcoinServices) failed\r\n"); // Mine proof-of-stake blocks in the background if (!GetBoolArg("-staking", true)) - printf("Staking disabled\n"); + printf("Staking disabled\r\n"); else - if (!NewThread(ThreadStakeMiner, pwalletMain)) - printf("Error: NewThread(ThreadStakeMiner) failed\n"); + if (!netThreads->createThread(ThreadStakeMiner,pwalletMain,"ThreadStakeMiner")) + printf("Error: createThread(ThreadStakeMiner) failed\r\n"); } bool StopNode() @@ -2384,37 +2401,11 @@ bool StopNode() printf("StopNode()\n"); fShutdown = true; nTransactionsUpdated++; - int64_t nStart = GetAdjustedTime(); if (semOutbound) for (int i=0; ipost(); - do - { - int nThreadsRunning = 0; - for (int n = 0; n < THREAD_MAX; n++) - nThreadsRunning += vnThreadsRunning[n]; - if (nThreadsRunning == 0) - break; - if (GetAdjustedTime() - nStart > 20) - break; - MilliSleep(20); - } while(true); - if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n"); - if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n"); - if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n"); - if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n"); - if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n"); -#ifdef USE_UPNP - if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n"); -#endif - if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n"); - if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n"); - if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n"); - if (vnThreadsRunning[THREAD_TALLY] > 0) printf("ThreadTally still running\n"); - if (vnThreadsRunning[THREAD_SERVICES] > 0) printf("ThreadServices still running\n"); - if (vnThreadsRunning[THREAD_STAKE_MINER] > 0) printf("ThreadStakeMiner still running\n"); - while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0) - MilliSleep(20); + netThreads->interruptAll(); + netThreads->removeAll(); MilliSleep(50); DumpAddresses(); return true; diff --git a/src/net.h b/src/net.h index 3e25044ce1..2da240123b 100644 --- a/src/net.h +++ b/src/net.h @@ -104,38 +104,17 @@ class CRequestTracker } }; - - -/** Thread types */ -enum threadId -{ - THREAD_SOCKETHANDLER, - THREAD_OPENCONNECTIONS, - THREAD_MESSAGEHANDLER, - THREAD_RPCLISTENER, - THREAD_UPNP, - THREAD_DNSSEED, - THREAD_ADDEDCONNECTIONS, - THREAD_DUMPADDRESS, - THREAD_RPCHANDLER, - THREAD_STAKE_MINER, - THREAD_TALLY, - THREAD_SERVICES, - THREAD_MAX -}; - extern bool fDiscover; extern bool fUseUPnP; extern uint64_t nLocalServices; extern uint64_t nLocalHostNonce; extern CAddress addrSeenByPeer; -extern std::array vnThreadsRunning; extern CAddrMan addrman; extern std::map mapRelay; extern std::deque > vRelayExpiration; extern CCriticalSection cs_mapRelay; extern std::map mapAlreadyAskedFor; - +extern ThreadHandler* netThreads; extern std::vector vAddedNodes; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 754268b799..1af0fbaf7c 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -345,7 +345,7 @@ int main(int argc, char *argv[]) // use exit codes to trigger restart of the wallet if(currentExitCode == EXIT_CODE_REBOOT) { - sleep(180); + printf("Restarting wallet...\r\n"); QStringList args = QApplication::arguments(); args.removeFirst(); QProcess::startDetached(QApplication::applicationFilePath(), args); diff --git a/src/util.cpp b/src/util.cpp index 6f33c8f44f..3f62be68de 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1617,11 +1617,23 @@ int ThreadHandler::numThreads() return threadGroup.size(); } -void ThreadHandler::removeByName(const std::string tName) +bool ThreadHandler::threadExists(const string tname) { - threadGroup.remove_thread(threadMap[tName]); - threadMap[tName]->join(); - threadMap.erase(tName); + if(threadMap.count(tname) > 0) + return true; + else + return false; +} + +void ThreadHandler::interruptAll(){ + threadGroup.interrupt_all(); +} + +void ThreadHandler::removeByName(const std::string tname) +{ + threadGroup.remove_thread(threadMap[tname]); + threadMap[tname]->join(); + threadMap.erase(tname); } void ThreadHandler::removeAll() diff --git a/src/util.h b/src/util.h index 735e97ddd1..0028c3c5f3 100644 --- a/src/util.h +++ b/src/util.h @@ -630,8 +630,10 @@ class ThreadHandler bool createThread(void(*pfn)(boost::shared_ptr), boost::shared_ptr parg, const std::string tname); bool createThread(void(*pfn)(void*), void* parg, const std::string tname); int numThreads(); + bool threadExists(const std::string tname); + void interruptAll(); void removeAll(); - void removeByName(const std::string tName); + void removeByName(const std::string tname); private: boost::thread_group threadGroup; std::map threadMap; From 87e3d23c39875e0337a9c5f1d833f64d385227ef Mon Sep 17 00:00:00 2001 From: skcin Date: Wed, 27 Sep 2017 14:54:26 +0200 Subject: [PATCH 009/166] Add setsockopt(SO_REUSEPORT) since SO_REUSEADDR is not enough to reboot on linux. --- src/net.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 13c9847cbf..ff96fefb60 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2206,7 +2206,10 @@ bool BindListenPort(const CService &addrBind, string& strError) #ifndef WIN32 // Allow binding if the port is still in TIME_WAIT state after // the program was closed and restarted. Not an issue on windows. - setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); + if (setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)) < 0) + if (fDebug10) printf("setsockopt(SO_REUSEADDR) failed"); + if (setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEPORT, (void*)&nOne, sizeof(int)) < 0) + if (fDebug10) printf("setsockopt(SO_SO_REUSEPORT) failed"); #endif From d0a325a223c300f67d0ce9025f14786283a4e3aa Mon Sep 17 00:00:00 2001 From: Nick Boone Date: Wed, 27 Sep 2017 18:04:44 +0100 Subject: [PATCH 010/166] Remove underscores from poll text --- src/qt/overviewpage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 31afc0c3a6..a0a25e8ce1 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -208,7 +208,7 @@ void OverviewPage::UpdateBoincUtilization() ui->labelProject->setText(QString::fromUtf8(GlobalStatusStruct.project.c_str())); ui->labelCpid->setText(QString::fromUtf8(GlobalStatusStruct.cpid.c_str())); ui->labelStatus->setText(QString::fromUtf8(GlobalStatusStruct.status.c_str())); - ui->labelPoll->setText(QString::fromUtf8(GlobalStatusStruct.poll.c_str())); + ui->labelPoll->setText(QString::fromUtf8(GlobalStatusStruct.poll.c_str()).replace(QChar('_'),QChar(' '), Qt::CaseSensitive)); ui->labelErrors->setText(QString::fromUtf8(GlobalStatusStruct.errors.c_str())); } From 55466369c248a593224df50b7a92a596e262a1cb Mon Sep 17 00:00:00 2001 From: "[IPSA] Chris de Claverie" Date: Thu, 28 Sep 2017 09:18:32 +0200 Subject: [PATCH 011/166] Changed VotingItem to fix sorting issues (#610) Changed VotingItem to have totalParticipants_ and totalShares_ as integers to fix sorting issues --- src/qt/votingdialog.cpp | 4 ++-- src/qt/votingdialog.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/qt/votingdialog.cpp b/src/qt/votingdialog.cpp index a9f98c57c3..0b25fc127a 100644 --- a/src/qt/votingdialog.cpp +++ b/src/qt/votingdialog.cpp @@ -288,8 +288,8 @@ void VotingTableModel::resetData(bool history) item->question_ = QString::fromStdString(sQuestion); item->answers_ = QString::fromStdString(sAnswers); item->arrayOfAnswers_ = QString::fromStdString(sArrayOfAnswers); - item->totalParticipants_ = QString::fromStdString(sTotalParticipants); - item->totalShares_ = QString::fromStdString(sTotalShares); + item->totalParticipants_ = std::stoul(sTotalParticipants); + item->totalShares_ = std::stoul(sTotalShares); item->url_ = QString::fromStdString(sUrl); item->bestAnswer_ = QString::fromStdString(sBestAnswer); items.push_back(item); diff --git a/src/qt/votingdialog.h b/src/qt/votingdialog.h index b23a775464..f458931a1e 100644 --- a/src/qt/votingdialog.h +++ b/src/qt/votingdialog.h @@ -51,15 +51,15 @@ QT_CHARTS_END_NAMESPACE class VotingItem { public: - int rowNumber_; + unsigned int rowNumber_; QString title_; QDateTime expiration_; QString shareType_; QString question_; QString answers_; QString arrayOfAnswers_; - QString totalParticipants_; - QString totalShares_; + unsigned int totalParticipants_; + unsigned int totalShares_; QString url_; QString bestAnswer_; }; From c7efd33ad9d6d74c17c3051bd5e75daa7a58a312 Mon Sep 17 00:00:00 2001 From: skcin Date: Fri, 29 Sep 2017 12:12:04 +0200 Subject: [PATCH 012/166] Close transaction database on shutdown to prevent lock issues on restart. --- src/init.cpp | 3 ++- src/qt/bitcoin.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 4621a60fc7..0b8358f3e9 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -184,13 +184,14 @@ void Shutdown(void* parg,boost::shared_ptr threads) fShutdown = true; nTransactionsUpdated++; - // CTxDB().Close(); bitdb.Flush(false); StopNode(); bitdb.Flush(true); boost::filesystem::remove(GetPidFile()); UnregisterWallet(pwalletMain); delete pwalletMain; + // close transaction database to prevent lock issue on restart + CTxDB().Close(); threads->createThread(ExitTimeout, NULL, "Exit Timeout Thread"); MilliSleep(50); printf("Gridcoin exited\n\n"); diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 1af0fbaf7c..66f4e898f5 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -339,7 +339,6 @@ int main(int argc, char *argv[]) // delete thread handler threads->removeAll(); - printf("Amount of threads left: %d",threads->numThreads()); threads.reset(); // use exit codes to trigger restart of the wallet From f764f8939d8afa36a8313a9bbb5a39ceed1c9d34 Mon Sep 17 00:00:00 2001 From: skcin Date: Fri, 29 Sep 2017 17:02:17 +0200 Subject: [PATCH 013/166] Fix headless build and remove ExitTimeout() --- src/init.cpp | 68 ++++++++++++---------------------------------- src/init.h | 2 +- src/qt/bitcoin.cpp | 5 +--- 3 files changed, 19 insertions(+), 56 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 0b8358f3e9..3f36d4cb46 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include // for to_lower() @@ -24,7 +23,6 @@ std::vector split(std::string s, std::string delim); bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); -extern boost::thread_group threadGroup; StructCPID GetStructCPID(); bool ComputeNeuralNetworkSupermajorityHashes(); @@ -58,25 +56,11 @@ void InitializeBoincProjects(); // Shutdown // - - - - - bool ShutdownRequested() { return fRequestShutdown; } - -void ExitTimeout(void* parg) -{ -#ifdef WIN32 - MilliSleep(5000); - ExitProcess(0); -#endif -} - void StartShutdown() { @@ -86,28 +70,11 @@ void StartShutdown() // ensure we leave the Qt main loop for a clean GUI exit (Shutdown() is called in bitcoin.cpp afterwards) uiInterface.QueueShutdown(); #else - // Without UI, Shutdown() can simply be started in a new thread - NewThread(Shutdown, NULL); + // Without UI, shutdown is initiated and shutdown() is called in AppInit + fRequestShutdown = true; #endif } - - -void DetectShutdownThread(boost::thread_group* threadGroup) -{ - // Tell the main threads to shutdown. - while (!fRequestShutdown) - { - MilliSleep(200); - if (fRequestShutdown) - { - printf("Shutting down forcefully..."); - } - } - printf("Shutdown thread ended."); -} - - void InitializeBoincProjects() { //Initialize GlobalCPUMiningCPID @@ -160,7 +127,7 @@ void InitializeBoincProjects() } -void Shutdown(void* parg,boost::shared_ptr threads) +void Shutdown(void* parg) { static CCriticalSection cs_Shutdown; static bool fTaken; @@ -192,14 +159,9 @@ void Shutdown(void* parg,boost::shared_ptr threads) delete pwalletMain; // close transaction database to prevent lock issue on restart CTxDB().Close(); - threads->createThread(ExitTimeout, NULL, "Exit Timeout Thread"); MilliSleep(50); printf("Gridcoin exited\n\n"); fExit = true; -#ifndef QT_GUI - // ensure non-UI client gets exited here, but let Bitcoin-Qt reach 'return 0;' in bitcoin.cpp - exit(0); -#endif } else { @@ -232,6 +194,8 @@ bool AppInit(int argc, char* argv[]) bool fRet = false; + boost::shared_ptr threads(new ThreadHandler); + try { // @@ -273,9 +237,8 @@ bool AppInit(int argc, char* argv[]) int ret = CommandLineRPC(argc, argv); exit(ret); } - new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup)); - fRet = AppInit2(); + fRet = AppInit2(threads); } catch (std::exception& e) { printf("AppInit()Exception1"); @@ -286,8 +249,17 @@ bool AppInit(int argc, char* argv[]) PrintException(NULL, "AppInit()"); } - if (!fRet) - Shutdown(NULL); + if (fRet) + { // succesfully initialized, wait for shutdown + while (!ShutdownRequested()) + MilliSleep(500); + } + Shutdown(NULL); + + // delete thread handler + threads->removeAll(); + threads.reset(); + return fRet; } @@ -1127,12 +1099,6 @@ bool AppInit2(boost::shared_ptr threads) // Add wallet transactions that aren't already in a block to mapTransactions pwalletMain->ReacceptWalletTransactions(); -#if !defined(QT_GUI) - // Loop until process is exit()ed from shutdown() function, - // called from ThreadRPCServer thread when a "stop" command is received. - while (1) - MilliSleep(5000); -#endif printf("\r\nExiting AppInit2\r\n"); return true; } diff --git a/src/init.h b/src/init.h index 5d03936f79..c8389a2299 100644 --- a/src/init.h +++ b/src/init.h @@ -13,7 +13,7 @@ void StartShutdown(); bool ShutdownRequested(); -void Shutdown(void* parg, boost::shared_ptr threads); +void Shutdown(void* parg); bool AppInit2(boost::shared_ptr threads); void ThreadAppInit2(boost::shared_ptr th); diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 66f4e898f5..54468fbf9a 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -5,7 +5,6 @@ #include #include -#include #include "bitcoingui.h" #include "clientmodel.h" @@ -40,8 +39,6 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets) static BitcoinGUI *guiref; static QSplashScreen *splashref; -boost::thread_group threadGroup; - //Global reference to globalcom #ifdef WIN32 @@ -324,7 +321,7 @@ int main(int argc, char *argv[]) } // Shutdown the core and its threads, but don't exit Bitcoin-Qt here printf("\r\nbitcoin.cpp:main calling Shutdown...\r\n"); - Shutdown(NULL,threads); + Shutdown(NULL); } } From 2c780bbefcc10ed614ce4746face09d1020ecc35 Mon Sep 17 00:00:00 2001 From: Erkan Yilmaz Date: Sat, 30 Sep 2017 10:36:09 +0200 Subject: [PATCH 014/166] typo in UI dialog (transactions dialog) --- src/rpcrawtransaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index c530a8e931..a479d4d0bc 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -103,7 +103,7 @@ void GetTxNormalBoincHashInfo(json_spirit::mObject& res, const CMerkleTx& mtx) * unknown / text */ - res["bhLenght"]=msg.length(); + res["bhLength"]=msg.length(); std::string sMessageType = ExtractXML(msg,"",""); std::string sTrxMessage = ExtractXML(msg,"",""); From 96b0611f29d271a67361d06e4a8e2752d28c059a Mon Sep 17 00:00:00 2001 From: acey1 Date: Mon, 2 Oct 2017 07:31:20 +0900 Subject: [PATCH 015/166] Obsolete contrib/macdeploy folder You can delete everything in the contrib/macdeploy folder, because it is obsolete. I have compiled a working App with the folder deleted. --- contrib/macdeploy/LICENSE | 674 -------------------------- contrib/macdeploy/background.png | Bin 9018 -> 0 bytes contrib/macdeploy/background.psd | Bin 66096 -> 0 bytes contrib/macdeploy/fancy.plist | 32 -- contrib/macdeploy/macdeployqtplus | 758 ------------------------------ contrib/macdeploy/notes.txt | 26 - 6 files changed, 1490 deletions(-) delete mode 100644 contrib/macdeploy/LICENSE delete mode 100644 contrib/macdeploy/background.png delete mode 100644 contrib/macdeploy/background.psd delete mode 100644 contrib/macdeploy/fancy.plist delete mode 100644 contrib/macdeploy/macdeployqtplus delete mode 100644 contrib/macdeploy/notes.txt diff --git a/contrib/macdeploy/LICENSE b/contrib/macdeploy/LICENSE deleted file mode 100644 index 94a9ed024d..0000000000 --- a/contrib/macdeploy/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/contrib/macdeploy/background.png b/contrib/macdeploy/background.png deleted file mode 100644 index a5541495b1a515dd9c23c0bab7bf966d881502ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9018 zcmbt)byS<((r<8gcXusNiW6LlYg^o*c*0AN7J^&x;$Ez!Xlc=6#a&x0Xaf`rRtOXV z7tVXm{l4$qv+n)lX06Hd?AgEh&CHhBYdven8R%&c;nU*-001H_O;sZR0PXj^0CCap zHT_3)od5s_nwF}PNx;&l0^5OzhOfb>f zfG)VW=*m!517KP_r(qxzm4o(4m*6@K37tfiL{zvj4iqc=76TvktAccR6fm3X}t6Wr%3I4Y(@N~uN{ zebV%~$&*SAFB}lUKM9twSws5d1s3*-&i%!dNTrs_sWs@^{n*twjk8fO;`;Equ!3*& z)99z}JD?{)IBWc7#==jj7nxga2npS!pK?QwFmO%Z@e-PAqf@d*@&cluP!kg^EG#v& zcuoNBJ6=j$_Kf$D{FGc0_-W+t_|r(WB3q%zbei_J&4-ecdm7slmg1G*Nz{bm&-0*R z<9EFHPSNc|*cb-(4bMo`{S=D8t&Bg2t6e4N;iay*2;}w4FF{>v>B()%4l)Iu959MF zRXOHCk?ubGhHfRo5=~BY!L-n+T|fS;(HgUaS5{f0Ttu1)1rC!Ymct20F-|;fq zY9d?}iUcyWCG!d#)`UO|1@%`bjY!>r>%l@kS8yr)qYRKt69cinUq_5AS2~81ho4Z~>BTm`(Yq zgtHRrdqf0(gP(+zi{|K1Ct%4ETYNF$mp6C*@`5PUR=;N6-2k1dM~8gsw%q8$@?mrb zkQsp${a(T98{BCn35~j;dk!`F{ zl)TZA<1=1Q_3UY)I#~RY*Zm&dc=NL-f|5Ozw?MDXOkhF4AXqZ*g9*PJLR)|vOaITy zmWW-S&>_(zhlXq&ZjLT(Ude0)=42%1+^xd`c0|vHPi+6Dt!ThGP~WwA`FV|5`^xR> zp?70bY_!%b9+Co-_znHF!ncL3iyo3i!f38g>{lBWq2R$!VI|E-n)=lvWZt-Q)@YOn zNjC~Z1t*ULBSenb_=5>6Y4?AlSKJHK$~gIb*N;~r zKP(w6Q;;2Pge}m8k5q&$p{aW5l49GcD)Uj6r%@V)hvQ=zq!<*lzE{>V(Mlm#Hpo!M z<5LY&<_zPw=4eiLtL|6Jzs2k|KW#|}F`H=oKSAMS93i>WsVV9*Lyj(Y)rpit(xRg4M%!3Jhlife z#Ma+^kd9b7T%IUxXfSlBOvfPC*VETu@fyFRYr%h}{MSf93&`JJa^>>RpSI7RRpp95 z&H50s93C7Td*t#nvan!~j1u5yf#k2DYt2;6GdriJAUnITp0(B0&DOoJF&rG6@VO4X zQY+g$6_lg!j>=;K9*~PXT@VD4CH$d|OFDu8%&LV9PrUK$YPMvGG0=Xcb^`ZFXRjL! zA>Z43Mo!7mhH|sF|Hg*f!&b!f=l0gC8b{i;4(nA=(1;|urn#vp6(!~G-@l`{UY?>R;NW8(L|{9(A~x6AtOHG2*Hi8ykOHJzyt=${$Yu z6>k(OMij|>WX~1FW)#g6j>?CPqfNs`M&d;WjPL4Ts7UeU;;Bk>u*_HP4u_cS?d=7Q zrzNd>doKx<_gh<~jg+cqFZ>QlL9J6A5z!<@nN@IyNF6!LW6&0na zEfHf&G{YL67u*?Y@})qLOd_PRLsO_=|Z~as5u}W2SXx}4LFZiG-)Sa zv*7{~G)@78@bs|3=Q;*&Gcu%8IxlW~K`!C7wZfDn2`@3ddgp1`=3R6&sfO{XQ^;@d z@k#r>DHTlj(@;^_?f6j5Y(OQzS?OHhw$a0R|24&r*PsCNA8Sv#*YoU zaIe)G^At7Kh4QHbswhG|lT0J&nT+?@MMcRX_{z#(XnQ}#>WH9+(UZE01^F+Kvu*1U zr<&B)i}V)9*<)s~KULLYTSyssPZYX%cBam-f~!1YL?MLTYGY-!wY9~Uv$gboyANvJ z6SAM4PLWZ(kg$V}q3_1M@SGSNzCL`(%Y!$JmSkmV2~YU`-SjB_85+k|4hTL~A~9Ia zrFh$j&JnJt6zuD3C-l8x?C?-1&E6+p`Nd>h#MN5HdSu~#+(MSAAH#{!iM-STq2mWXM!=-(qGi(08{Qxf`&3o6x6p;4 z+IS=j02X@;qo%A4jrzXa0NxB5`y~Tw>j_KrOxbSi0A>~zEDjt)q78g&sU4c4zUl~= zXC}$pRbn&@b@eZ|d%z2luo6uohQ-|OR|Q2ylR?G8ud!nW-pI!Lx_u9059jJjy10mVXep2_-6h%;GOl?5ZEm%Tp)7*Z_2TTo$Ro0!P3758+ zxaf<1Uqs&e6Ej=MHPy>ESCmb1-ePTSt$pa#`D9u<;}B{yQJmcKgqPE|w;5gw+IeA+ zB>XHonM|niou06vM`1yMlHCCre>|BVg=Cb;bZye?jP}=)D9pUOcv!~aov-(ijIWRq zWi;3V6pmR3nABFD7%kNQQ(j)PF(v*<+}}14S>E3E@_W_OCsdaq9Il>d3UVL_&UN+I zekkv=itkhW0Lhf#@L?fsQ_4#eTTf)u~Z?#ChQU1O=C^5Fb9v9CEarQ_S zQ0^h%+~6ef4|9v)jI@k@0^-T8oG*-K!kvElXt}Ai%#@nDpJS{K194v;RkoAjOw2z= zW{Boa*|)uk9d}9yF^)a)O?-mI{2}MsNc^Q-N_$Y0O&mBj*|woXlo7&;Zo44N%el@f z=OpABZgN$%OS+f?QzL-uZAgXZqwf`p32RODK#KCFqv(gQzk^~Cr6fx9OO>7%HJT_J zP-tlAj&5?kSqjZZ;_-5ILnm~SjpbSw19?}y+&0<*>3~euzG|_lG5j`7o8_=!Txrlw zec_B`>>p0m6YU<62znch)Sm?Jl(|9rcfP#8{Ku3mca+LD`zb608-P8uc?2LWUQ+fg zek%79hRL)wsDyuoNkh#0J!lZX4_z{tzt@0eE^}jEMlR>*!$<$L0K>^8qv?xJlCdxQ(!hVGn?rJKlbrQ z+eqIO+3Os=_!#-W6yI=9U($e*2bm62jM%b<3c?cKj9gveeiTkzdj<4&mfosd9z%m^ zVf{*#)xpTQ*{=}l4b~c>;3T^ta?(kpOn7ZDGi3Dy*ll4g$WrzWr#Tyw0iBj}(y<`* zS~C=7fN=CNrV(>MTc21oyLs`rhZsH~kRt0atbd~X5}xxS{~~kc$)^)L=#`~s2d*6F z{lrPk9?&X1KRcI7tSC};;V=+X$Y9vx9(J5ZvPy%ChON50RjI#S4S(QVGlq(sUn9U= zNuPmn>zDWh*tXd&V%^yR^=PYJGvBM@VAC3KVg7YKkKp-{O*HKJK%kaob*APn`VZ>I z)4$M}x0M~8X)st@uf-Tz8%291%t1VgHbY96>*iuu9wM_o+S`!S;1!bfhMOTPW$YOL zg9W?I^nKz_AXPd?;&vu`HxkjL3B0Dbihzb)jzDkUgOa9AZK$Y5-7Qk1Q0obutM z2?QnpZsZfDq;Q?2v2&lODBPIkNFNk@tU#6xx$mZIc+xXguxUA;4we&7@pTXxVp)t! zfB&Qoj=*_o=9KW!lBu#ZE|e3ZMQv$Tj_$`9i!R}bL(C{NP8p_+FKCPt(cpx?JVv%) zONLvmJi!pnpVJ?wonj?La}E$7q2$MH1cuYR5zO?NPrcU0XD2&78S4NOSh~xGn1g6E z)di%~x(K)oW9b(`Dd>u1GcCwx>YLl+;Oz++F(rYtRt{tulK_>{Rb$DeQSBBJ5=CIn zm4^e0!H=GrGDf2X2YbCe>N>T_T^#t*!3#qH0duZhaBF?eF@*j@JWKH^gn+wZEhV-y)ll(#yGCa zJcyvwJKUnS&v+EY0$?pmGB`b^@5#;>59WeQf4gh~C#s*BzSpFy)WDLPHh)FrOe*oG zGfh@&jJB0Ro#8n5>I!vw$_~~*sO?`>P?Lt?c^e8(gfD8FHVCB5SkR zw$>dW@DhW-IgDNuzo*{D(gYaPgD?$ucG80#!%`nn4o2Ylq{cyGwGTyxI-1^;q6ef% zyW8-KXLztJaCl`n3P*hd@})~TOSGGDlYWESzkF$4X%zMJ60+ugNOWu?H^APIqLWnk;g>d| zP9SN$X&F{r{R~;rU0Dn9*x3X5yP;NlD>PC0zQ!@!wIDO(owqs~sB|&F&yq@n= z4712Ta-^y?8GeVINaho_-kY3A>MPeUozy#_GB@~td_<}NptUxf1j3L)2U6=cT{(xKS>qMj(_jr;jSmYHvZUWR zC_{N^9A`&D2fiIR!?AaD>*04d@g~?fwAu(lUTX!)6)4+<-;3zbv@qqq7eVz7i!m2} zHVHuNzbA|h#j3(HQ`__WXC_!Rfboqv>nmC?K)9H zPSi_V5mHHVotx0FAW?8vH(pV865R8h82&YR;Snt(bnske3DB)n?Jgb3%BEt(G*iYN zEh>|P4mAtFn0SJ0V6OLT z8}+ z2o@acH&@9I1rxFv%Ez&+Y3VTe9pc~lQ+n0({gkI-dz-yK0=NvyRIrn@<-VHvzEmgJ zST*S(qTF?kJnelmV(l(LX^Tt67l!o#m&RcLy-Kx^(C-@~PH@K5w9saDo2n8EIj9_R zGm$PE%~lqdfR4vg^jXt*{p9;|2gmEn%X;g9GyzRFyD?Bpkkw#2O`8P4@`^2CT@;%1 z`rG8SW&1FT{ZE+O5yD-QhJ9EjGvDi|lDEXE-HM8e!eT@LtZwVkyT&h^jUX@{Dzln5 z+}UW0^4a5oD?Dsn>GhLbrsb~9TPCR-Q-w=drk$S`N><*@6&olOjU?a){U#bVUz6}S zm*JtpCS)h&_nfTCo^dUm#Gvh+HY)#Wgnc{j^+nx)?3U`oLWB*3#USyg%Dzx}N}7@R z7mqtsa)E5OEiHby=&PbA`N7pYWfU%feg-*T!5t=9gSdF0ciiS6N7Zvi>P}Swwdb#^ zA>M_>eZeGZ>8z!eZ449G`7U##rr)jogGtFJXo@V%7^#m<%@vr&tB#$h`oR{t(wFH1h|NY zC)f3z&8meds_;~My=mEtA$f52_|7fV`SNPVdFzq+^)$gIF|-AP6#c%0AXmPko(tvJ^xnykFI;wKOq0;%B%RWA0$fqJE+5}nSlVan6o^x9A2(kQKk;d z`W7HpTU9l`-=7BH?crPGJ0U}=J)%$ig9-r%rl%E?v-{c%&Hk|!#f9=2fIb5%1AOcD zWdIdATInsJNb?HfgKi0yji(iTD2uEW3uD`n44sT;aqXWl{uFW}Mu>m4w@kvo{!nsZ zU!*7D`gKkQC9=ZJ-Wl!H3G!$Yf%9IRh?k54Dbixa>dXk#%4v~p!XQ5S@bmsN97cCK z($SZNI0h|6885dbly$s`2ud#Di`2nBcI0-0eXNRC1!({1TX~HEUB(p~kY9Xk2jFtw zRM_>CNyP;Y=eFpxGeN0nAig+#Rxq@G7hf6(;6Dfu)_*^&|5HfsDgKlEJLNUb};T;4pSn<#sj+;+cx5-0b>o-75b# zo3~5A8d*c2%HL3HXTScY6-XiR1FbP^RAT4$)$wHx+NLnVF+N!K>`C=rbuh=@mLlSv z$0R5kZ^FN^%O4OgnDTyL#kRMk^C6tnvrx^~+Z+#;uT%=Y)Fsv~x$SPpdv>Wju-^C~ zHjFXu*9abCxr^O)-SWrA?TmlMrvtvNyPmY7VnuA~RkSo4uY|;wvpld0A)EwJ556OP zy|Y5b;G^j@dNk{oN2mun3`AIRBYkWv7$kQ^kh>pTiVi{P8u1wlt&r>Pz%q zCx7~l;k(99inJ7O1L6DwGpY7~Iq6#ryC1gU*lUmV zGH*xm-|Jg1DNna79!7kY6!~ZSwLQw>A=|)~ko6B|4{9w6bdgY6ZWK9C&eYP5~L7Ll=yUoN@ z?E8pfuWyJx%IvSkKFpK`Y?(+qxrk2det45wnx9IF9V)2ZFFs$ERfuXP7sEX>2jVa- z(cCMU^KUp81H)?KKTWw9^lfPWx9MuIg4lhKO!w2_As1j-_)lw#ERV1LHt>g_JYGCG zdn$R)^FQ{>eUksj_IuF%hrRMZ|DWXFDIePZ-?RyOl@xJ+x7E6R9rOEY?Dxfk!k2{* z`=NL&ss5|JaBtq%A`UWW+GF3fs^vp*#qnjbdg0Ti5?UL)up! zyZiSX-MBI)uGJi)eg{QD_WB z`KBt$xa7f(j*f~73kOE#=gmz+hIR8`YJoF%qC;nAXReU+Ya3Qb@4Da?bcfQmG;p+t z15&*ETE_40;^N}keEm)p@qF!xjewx0&hHAvrwCS;BUos;2M9;U9$bHZd8wI`D7QRA z2KJ_*%MqSdPfr&79mgtv@30C^#%0a3=K-GkIG{o*KNJ6cyC`8D&mE|1#0#EL#P+hl z&%s(Ztg8IJ6$s*qpUz}ry=bWXq#Yz4ufOwDoV|#o(@r9y9|uQ(#WuZAWoRXtUZ8}T zFn~W0?UKym_uFNMJx-2+YRTtgS3R}8Z}DW-t919t68s}fL>qAkQ+UNbu*K&VuiHF9 z(|hI9OsE*KH=DYy<*9|3S%+2BYw`&=R?aD$X*%N%91osjuKIQkqg*2S9+^pSvHv04 zzq3|7w_g5?j_m9z)pAgy3s1!lqV%i&af7Q9#qc;#%eYQEk%?*~F%Xo+=4Sj{SL$F2 z{>C%W*LQ(kAI|1Go)%m!zYD3K5N~M)U9+aP(t*sM#5j0f{)jLwPv%U1$snAJf5E=Ue*KyE%Ta(G>Y9t8p_8L(gITtDTP7tN4%H8oKLP zJ9)5B9a|YYbMZlH0PKxrokH%Cz>rn$V8)oT5XOfmZwKXBdtH*8e6rOvU3niBOcUV) zcjj_}tMzfQb~^TZTwe-PKb>UuNXs1#x_zdO%J}%oyQftn5;JljEab~F7q{PSzTNb9G59)~f%#kN3Z1+T4VB^NqaATbPQMK+i`2BFtx1+< zLAIJbz0*T59kzmxB9|*MX4M$VCS#@vTaAU2nH*LRcv@*5!cp#a&+)D}^8;yg&40y@ z38EHFIC}|l;mD-1s%1qg6ScNCmwBJT5n$|-Qt)FH#M`b^Sn1=K+2=Xtl(|mcOle

G zv*lfbx6k+_FHNTyo`sT@IYdszg^@fn2oP>9RWj>dpn_X}p4J$hZOB(cU^&30F|_jQ zg!5oLld#=Dj@Gk0hBDxjUjY}9zMEy?72aGB>!*vl8=C81M1;244&V)hrL2~V@_Gq)^yy9iGYX4dyW{`yfZ6eK0M?r1h__g$g_JwaE|gQwi*r29WZ zEYWvRid^QYx`?eNLRaJTBkjU3U?g5#oPLE;O%~*Cizw^BaYNSMr}IsZTF3oz4AszT z|9bUm2W{r$)F7Mry{&jWtW~`4>V#}Ct4A!kv)XJ(zGgB#xK${EU-DG$VpLNhHS0`x zRNx63HZw`1^K6L90`HBoF8%mZku!KmOS#Iy(3oG!#yg?Ot*icPe~<|6S$p4VRkuas z&wP<4U4$ZcAhLE1tO&z&37EEIF2NS&PPnelFLe6CXh}YCI&xe&59-)GJFGp(oWCLq z@&{G&G-r??|B#&1VSN(_yWZa01(9U#k0qJV<5um6^56<^Ne50c`O1rUwD&oT;EJBH zdW&I@C&-aw(ab!GTvkxIJY|V`lXz>xR3@WjYR&8+R3M{IpSPfat~^WGJY#;F_OBn!Fkr@zX!a(x&i>Ebe-d4P^yA({&gAU l{u;{v`!34ERhI65N1|bFiaEP9y~%wb)>6|`tyQ)S|6jmq=GOoK diff --git a/contrib/macdeploy/background.psd b/contrib/macdeploy/background.psd deleted file mode 100644 index e0a8c9ab9da81e052dfd9daa61e594462ef0e8fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66096 zcmeHw2V4|a*Z!Slm#%;nJNCqiHMYdHVT+2rBqnIoC>F5Cl5DUS2x^Q*4Ot6nL}gX7 z7A%Vm%c={Apb>?&p$IHeuL#WlxibqcCGYpX-}n9B{Jy-y{C1do=iYPAdG0yqo|!p2 z+oiYXNWu~E&x#OEiBC4MB{&xTJiGKBI7DtM9M{GkZDmUFLu7qFyLCCU~_&g&Dv5M`@qsn=n5XTj)273_39z7gaFbZ>g=FP@w_U9(- zv6J=gFN{2E;hY&LGA?DLH|dZ6eeh|4Pa&w^Bm!jzSCom32cwKVDBF0Hq1=kKV1Eja zd6Q;OC6?5kSvBz>^T;GJo8TP&R^f9OpK}<<}hGb8}po0W2c}A zQ-RtPGKiAksC!UyFd`ktB~~>5(LTkn};)2PsmO{D9;KBtP)? z_XENeh%3HCB7Glf~vpr0qQdl`W8Q60oW&;KmRYakRv>8mU2S z{RrEPB%LUnM(qf{Rlrg{f8-Sfx59Ufa!My}h*h0gr-a(|yj8)eS#{o!EW)+kFDA!w z`&(y`9Kuysi{(O|+gm+{Ry1crM)W zEy+hsq*#;1bCHhu3L4@&OZckUGOb4oEs6>42mI|8pI9#$y#Owcy}e+Z=f;QpWo8m=z;RiV>{1t)#e(72hv( zUaVMZ8N`xxPi&2K^FEd`RD4%bAugol7TcmS>oLlu*6XtCdHEH;Y)nu#W+)$3l#e`0 zMN*zMQ8ZNX$R)z5tzF;lH zUaZ+>UT%)OiX$_C`j>q(_CI%IzZA9^g}wA&!a>pp$sQy>@PF42NUP{yv6f3-Q}UXU z*ZjZhH6{C%?AOwMrBzf~MI~=0c}2-9T6#rEA0&PFSM&j^sEpWPC9x+C6>gPrM%)}q zj#!zsEEHdsFw4sjbiruhruFqh|YXC(`V**tfu`YYiO zPw`U*rwE65e80^uRXEJRvjF!rfZ+P*7Kt(O+}m%`QL2BP=OXH4u%l}%XW$Jxx{AB# zj<|R;ix$6d48(Pcc9|IP|G-%0(8NE2w7$BrVv_e9*HC-pDz++io&&?oiJgX^BS z*-z@9<+-)icu+ve9Z4ZH4NU&d&;Js8Ol3F6bCc+F2JG21I0!9mPEg-j;2#e{l zm^6#2w3y(MX@9Q^#o8e#OBe%3_V3-o=)ZUS3nUB*`?qd?frRd1|JDr>_96YqXwH)x z%XQ(pa-F&M_&=2EOKRgS#`R@xO6LN+SK93&ktuoQGeX=7lyZ0CtaQFZcpc1?R~^9t z4BJhah6A3+aE=PCa|!PrOJr^)bs>@Ynw*Pia4Nn~Cl4ebSeA&2Hxt3R5+b@-xMCIW zhQUo5-q+x%Vzkx1%0T>ACjwEEC8CBvWg_}i zHfWTAjDU*Q`Fb(}0-~-0V}S-wFCI{M@*1Vmw**q(K&2NCF_pZTh;^XJ%Tr?lrXPwE z2F7&Y3qt4;b)HHPP$|7kff&S@xbZv`n|BAOIxnRTjrc(D$!iD+)DWfG(=$K(C%_)3P1m&q9u0vrJt+B4p~AR|ds zv4R()ARt-@PAW4@-B>TR4lRHdugej5bSUX8%56X=W?>Gz!C6!hzyv%J)kUNdxMPHT z4IuAj$`i@zK+$AK1Xc>R~)&U zyxxjz>6iotoP!vQTO=N85{qE8pl=q0;f4_mP%jO3ia?VEYEVc)D}^1zaaS@15;4;{ zHIope*vJBGAgoj{UQ|5v+KiggjG8a+sZ^?w49R;kKJti*o3fbiV$j823^q19X4o)< z44nX*Gw;j9*92l-)oMzdl)e}mlDPA}yqg=Faz|%21}4xQz1@nDV{AGU1LtgF;6Ot# z9Sjc}#y_isZv%j)Kq^$TKH{g4*odt1fo9;$vIvQwys8lG02}ytZ^G|ka}mZ(RI9}C z!KR?qmbmFmf|Iv|?VT`@rsD{8e>uZ1l_$I=U=?p3W0T6(zCZ8#TQWRbxGR-`oj!%TWvjqtQ z@>tf`tP8b_9Uap~R{tJ0p4b($%XCPczu3)KbA|n3>V3h$&D5Z^uY7 zJ(sIZ?mYZhIncm`(v)Zc8EXN}My0@v!Q?L5=zGW6AP0%%K#x3NbL|Ca28h9}s zw-?po1gSB#J%&nlG@R_?qZ5jF_MO6i%v z99H$>(F6txL}!Jz&VY=mx}}y?$Dn3r)rro;9SPe^T|mhVRxRKLp$wJGYpeAv6yD3qng3PRI z0daChG0|Z1d{2cp$UVKVmgW;@fjnWFEsUYl6%uRn`U*UF1%~1olW3?`8+b%0D&E9M zgBeGiDNtwNeVv(G_kBxj*pkUmhJ$1j**voq*c1q;47G(J#c{-1@z~j95LP`)D4{vU zOgkGAbp|$5cE#d>tP*Idpg_eDptTUcu@Df|SRdF9!5}b1Oy#aqp^73yu^UEK z6%t!7jZTe5EUx0c@^SD^CAc`4k`iH-7lP);!^~)jG^)pbl2%!~#t(9VP=&C7c#)%h4I(9nOL)Umj7owNj&l zfnan6qsF+i0;d3&1$1n*;vrC3gcX6wq4r(TQC|Nj0zbmX$>k{ih;@(s6;TZ(N7x0qYTt>pZ;g`_36 z#<(i8*uOZ%^(-N8h<*h>m{jmP2IKeqNqItmJ*q+Po!-RuK)FpKJA& zSh@c4eKkZ*E^C+IhmStpdn0m-TON_sP%lU(vW}OkJSEl+Gq>A(v0s)-WX-R2Ng`HO zJ!!9neQAAl;v_+kAl`#@g2jM4$ZC~ua`h%JsAfIyA_wny!+SC&*SYI7}R|tKN0+FgT0B!svkZC z#=7u|M?_&YApXoqN>FgoH|Tq>^r)l8F|muP0gJE2U7F6x`@=SHs`m)-_&tlJ{dnN)p3st zv7Q-xWL*OO^?v#+@W>n|QfYC)E!hw41bukeW-6{yMsd zG^sT2;9<;yB zO8_zaqFQ&hDh@w@bGi==vO>J9I5*LAqZH+Y%Bp+B%;!t$lfC)r0)m zz|eCZkF|pPZ+q(8)?mZ*rZ+ZK*YKwUkDuwCP3kFTCG6V!fUnt$ z*Kb>G{q>cd0e7x6Cm)2K-}=ine(hUQwNu>lE!PXKY*Fhc62;hCJAORl`cl@!BSRLiJh4IaZ^477OyzBddJQ- z2lB3Geyp>gQqJvAHK?aF`%AAZJNE`H`pBeds zCmo5?wo7D8%I;Z%+c*-%xEveOqHX`L_V9IzJxz1Bn8l=T%*wik-;P`C`)JIaZ`${2cOg{HDo$o7iA{JD;cI+olXL1Ahp=z2~&)3aRXS_EN;boHQ&pskW{zrR;hO46b#Yi z)@ERTd^e)t9cO{P)xdoG^5GC*UxX)1cD;Yzv3XC?;2QVm0JVnK)-mk;Bkh(ykQ1A! zsdj_;ki&;Vwok`gD%xf$8@?EiOOk4r*Mo3v&55me=2B_hZHD})x0So|4M3w0UmHd; z{7&a#Cwr1AXMaRX*Mn#M&qC`}cWviBwaz7t{L-|i&m85yw`rN~i79+C#x?3&g1d7Y z?HKZ>>{s4a6p&_iUi-Ih4a=)UJop+tiyF7c?*dvKQl}?@PXN23YrzNAvRMGpzeL{;9Rlo| zFO#}$tMrM}$1j!{dvLUr{HEg!20Iog$GgG9>V1^rX&t@Nnvgbk znWL{9a8O@7i8)H@&JppDDwd_JQo&PW(<}^Y8;dp1{`9}OFg34D(^Rl-lEjzkLFJ#aQ%j;!L zTicokBU=?~ya4?rGV*)_QX}Xwk&i6=a1h^v)H}e}Ep|0BxSAr;bLf2@Uqt@={!9ml zvC*qZos-X=)@GX4l{7fS*CxXwX6z9)St0bO`E-5d z##b2p_$kVUg;Nxj*Wq&i=ZgdFoW6Uv0$T5|Hn!Qi`vUw{wT-KstlOL$3#}L2{mI|k z%f5U)fo!}n+_v(PTMM>9?*;rFtv=;jxIW%h*RDy#X-7(|emM4Yd=aU#;?@}3%JU6h zPk-3gs{Q%ffM0=_xeM=6NCu27_|*OR`8Kvc7&_Lx7TZ_u8#TdJ^z}m?%~E`D+(5?i zZODhe=T#=3@EwNpO^80Eg>CK73!fSV^yiVS8(hdox3-IlPZ}orSF>+_^9X#s{Erx#rZyA9Vb8umJ9hC!zQMup+iI^W=&-@mtn}-e?A$Zdcf!^wk|$ zeR*#)(mM3Q#%(tPTkeNHsT>%WM;uzb2=!n0;Fq9J;vir|Uah z+G@|PJj_SgElOh(aNvbKCcq}~MBl`OZCm1(Io7?BvO7Tkb4`~MN1efE&5bwK2VI{? z+TGW#*c^sgsQ={nS%f)5qJ!7&iyzm)G!eR!u!Ky%6y$gK6auYg_KVVqteYJ=nH0hVMiMTsyF8w_#NCgrzWcufc2r?3*8{OUQsvw*pAh@6 z)*u$&cJjcNMZ{S#`}gC^gHQTZI@r6#k-Ci!H3$ARHVwxOyAQX`z#WC!%YHw(vKg$s zaR@BZne#YsQdQ|UCH&%`?We-NcSUU9{l_z*Qym;uPprITHpZTzA|DsU=Mg*WMcQA7 zhB~!4S{o~FyPwW%arO7IcT{ftedjmvODS=w_5GRf4IF+wcCQtYO*?vOQ**@jZU@?6 zLU*0=M{HlI_4-pM=2e&bKqR{_{6SLY{d-vF2?x*Y?uRQjy?^CG;_~6zQ(+4cXSdyQ z^3bmJ)@1Fd`qm@6?W-d88T0azsAu=$Y-^h-x)}J?`z7=Vv6(X;mkD3r`*J_7>uej`og7DGEljuw zl{JW7=tl~~rk!?mLDR4A?DSr7_h3^rtvfX=qCJ|n$r*yCZt=^-rg20u>R9ZZElq=o zyh)g@mkdpsTw;jnk&6u%D#H`xDld;fl&|IH(3yq~8kwkqZiI~GgTOOD>xu~vUp zs!CXoidwiprvFWz-_!bYv@9_d5yo4F{##o={C4{oZn#BGPgiaj*H6sp`EODD@9^>W z)ITRd_ltF^^#7VAx>maW&r5&SgU!Fw{}&CE^sj=47yqN1fQMFy_T4if{zj;d)w?BRm)9dzIYL(=*>{$_& zB`;X{a#-E1*_+mwP-fK&M{O(G5C1^)i4 zlfg@R$Z7DB6-3g(%XxC=3ONs6;@ffiz>Bfp*yq${ejD#~-}mo$jZ#_KfpafG?*vH# zJFmRmP0Q*tcAjm12zIiA$?NM>eppT}=YfqUpAO49eJF!k=N%`;NB*zC(8Wey23}?i z9Vd^#&}DL&F~nypa?i_dAN)>ziIfzc9rcO7iYg`Ji#N=cb#e?CJ24;OrvFdPEgDyIs;~ z1{?SUd5nQ?*<6XHkEs1cSu~~RXASuxH2W=W`f7Dh>K32XBc}dNY1Wy^!)BhK^jR~R z$8frN{II!q>3gm^3~4(jjT#3}ETXla1&kWL^3hAx&y?m~{VbVg29EQbA4_Sw5gCQF z+U4MvlwMyrbo`!-wD0%54w$!M#Mh@YY2C~X!@M>SWAx-7M^1lD_fH-=RhLESoh6$r)#3#ok1_@N6ED7E`z@*PUGQ->{xEuxOG-+7MS`Z9al%(WxG zI-W=EU$x-+4WUOS5BXY0X}!&>lPG<<=s2Zuex9Q?zsT9Xg3^qG^Rs@R958fc9&Pf( z?$pu-iIhJ4T0P4%;1zwgB;dQDsz2z{;iFAER#R&98}`NiBHHBj`q9Ie{y}p(kUm4l z7%4sFJ;dt-HO^k|GkgK0O!;Nph-C)Qi>_-sa4OyX`B0ym6d+Uj)5y;QWLE*N_otID z(C6Rzd5?)m1n3SCG6TKPd7$@*misgFY17BuCO;odde0i#D~z7&Jj{1|#}hQUmwcx0 zw;g6pZ#p<9!mJC;@3-2pszor<1t`RVR$fzjOt|$`Yf4k+)yvLY++p_DO@`(g<@<8p zQkR<^y{3=tGnEj*hdJ?rAd4yZ=Yg zVL<-Zrk{P$l0?!g9wTQC?Rxn^+v?+du9P6}(er}o;itW0fP7Nl880T(QfKLUOrYy4 zU8V7hex+GKwkfIOwq)h`lNaxiZ@D4))4uVkgMj>jX5YR{+1YaS>1r3~;}+l0^s!sB zbJvrUD_mqAkpH67(ex*iKHk%B-m?+)_GN{4nFQpYHkgwf-<=rGS}lD3ih6(ll>TOS zoO*wBDDA~!vJ}X_oYnc&a+@`2_eQp(Pud1%(>rzd1NobdC+U!Wmom3D{*5key(8_# zl8&2aR^ORKRDKb`rIzV5y7O2^(e(%+bokACI&a~`F~Tz@wsKiVUezM9sZ23Pz12aP_J zX6?0mLk%}iZ2ycrD)uzZ@3&k|XiVW~irPuS%p{WOAX}`~2QySH4tar~8`g%?~ zO0BbhQ>4X_aI6vA9G||W{8-nAsoghFI%LEvN@G2S`I@oc=$f2MyWW*||8h!e#Wi}{ z<>wrFwt?nJ8=p7yPM7a8M*#Z1)W69Sny24KvuK>{@!=esg@5H0}Ib`{lWh zL}wEdYkv~J->i1j4E)Ful)jqTm8NX$-TmXy;WTTvohfhs_^)RSF9SUN#(nFki8OtN zG8>L=K`Z)Qqoi4#Db3l7#-1eUxqN3%A+4UFd;Pep^PhyIw-Ki;Gd4EPUPnre*wfN5S8TLLOnN&@(>6@Rbm^5U>@Zlq-ZoynCZaSWc zcimG!ot|}@2f~ks44OU=USz&IL;ipwnN-afsd z^~+miY^al&OB*e9>EEyKFtY5;9p?~CVcp=Q*56T@@QJU9A@7m?jeAxBZD!gzcKY;z zHm_+Ic@j?U8RQp1E3(R#`f5rav|K}Dd_U>l!{;ug4NV}szfv+l*iVj;L_xdGE3U`a z?lE$>=jW@!+pJCi?1~6k^fP-FL7XVj_mLw3yLUI5aP!6K4Q)Fy*t70epL6DsrY!6a z2X<~fndZ&!fMK3b>PpYKe&5EQ(&%cw;R#1bBJHG11?0afcsXsuq&j>YGeT^(~mAPnpvtdqtC6`etjD%=08B`%QMl zHNoASeqJju7i(H{Zm-E1l*aTKGh+~@ex9K52NW5135-a#%N`nE+thaZn7L1B*1+*5 zO7Ha_vFPJGnzpzlaL>-8-LjjGdXSiy+_!0xp~}`AdZErCW82v#8uigP84UP-*(;kq zr@4_kX+-sJbPv^X27U4caxcm1C{+Gv%^mgkPTvzaOD-Trj)B) zCnnJmy~5wT@b0_=p5BZ-qNW^#9>zNJQtowS@IztZxoue~^GOJu(&M=4)wfnlp!I1B zKD;}>sQ`b@<9drX}8KSR0+VF?0=)rC1KBA{l18h?0SrT~&>e7CMA>;ATo}u*w^w-nrbCc<% zc2h;gr|}JZo~2*w;0a%!-S{h`aS*viKN)#D=gF7fUu?amh;li(Mm7cK$!&Vvebj=_ zn*EfHDR|s{^7Fxi;T5K|qt`zkwsdN@wKVT$&7or|_g*|}1UY|}+_}u6ZdrUI6(q`C zLcCz2-fd^i>NzNmX8b?~7ts&nKIpS}mM78W(dBJEU+B}X7nc4DpA4KgspYEMoo7Am zJBHF1pLL_Lb78Xeveq}6`FUfKbecJTQ=cwAb3Z2mc`-vgd}n_`zJ&$k{Ze;m)5bY8 zBhV&0E1;S8!l51SLZ`2DC#d$5F^jrQxJz#h?ddzM!>l`F;ZIU#HP53C2G^lJ^P6}r z7}@Lu=Gp3EqYk&gu3=;k->*A;m3*^*?{9{a)~3}iYy!r(regx$G#I39&}f=>v+q+A zx>oyqPWvgw* zbW8Uymk#$ppw%pWwKL7|Z#-?@kTw@_`9OCxnKrp4xk8V39<%uKHV0xF`N7zCYS;wW z$9N)KKJL|LA(cf<+gwBykG~(_@y%UW`@IpcNawt;F&@ibk2(XtcxJpX_iOrGFSKi;>gffhGCDf;$Hu{uXmEq&h*qXz5^z&Yz8J>5|{Pu zGdGWBg-ytzxm$;M%)}(w-5;aJgiiACfq_@LHP2(v`ls3cXl?q%2PAVh4H$TN_vpT# z|Bg$x_C6_v)Fo?DUIF!3Kl%3>0Y3d#CDZ%v-mCgA zh^MdCY)A)xGPM(0Grp z!t-b|kj4ESe_#H1OkV zXsWk6il+CQsl=uysp7z=AGY<54W{zgfuEetMU&W`7tkbe%ucb%-}6@|u26YimMJZj zy|G|(iaa&Vl$Cdd;z~C+GmX`)O_8N#=3b*W;C0f)7dvq2IX9@Da=9k4T$sX{a`hC+ zB3WX^+Z2*@i{7DJp1DOHTIAiK2Gj^d{ZevLxU@V2je1{`#cHBx^!u7OtR@;Y#7xGN zLQK&#revHnj1xoe;(A;h_jL-%z01mGMo~`3wG<^e;`vu8Bqx@Y&F4{0kEQqU;#%>1 zGWy?R_ODr4 zEImz;ju{gFsW^nC$X@3{Q+_w=L0F2_YnlgD)Rt6`*KF~J_MEb)DirPPv_;iB!9>nj z)a1ilLHn#l6&3XSoJCC@h(pycSXAYT#B~-`*_6u$3l}Y_vOpa+b;+U%cgbKCmn~{C zMCw<~RrgcK>x3K==x6w)L|Rl{7wKQOsJez$pnt=n>Z(BhrbW#aQN&voRhLETw=JqJ ziqs7jRS}|$Q5IDf1OTHgYR-$)?^;xy6#$I2s0kNEjI*dZBNC4-*%ExHs@iB8B;Ifv6=l7g1}Y9!GjS1rnJ{)#Id9 zoK}mD_NkE=gbF?1(aM=o;b;h<^r?(SAyvd_!xOaHcg4i1T5k*wH!`LwB}d>|8oY$# zEyP(L>vTUgc(SP%E#b5J}#M&T0Lbua4d3;I|?A6H|h&T0ngLR5J7EB2!_bK z#x}ti9*jBDV!ALR`Lu>QJR~w)9i>Uov)PS^GDhNmLKVMAt6MIModGZLJDZD zVoXEK66tZDDl<6Tm;m*uV;)!pQmhq^iVVcT%MZg?FfEKUK5qNYc=`6~vK__Nn4r)y%#=$fKCg2eg zfm=M_j#WizKt3)wPb8}a#b6EYsf0uoPz7T{t6?3$D>Gu;PSQdE@GkNw@GcVuv)7<2 zBZxY5#Zhu_9G=U7VFxXfKqHJVaLZFJJfsLl3;Je37;YFr1N92WP7xVwff^K2&`Mzk zagvRUfe_5JHiAhAQfy=aHV`%{7%zHEis0>ln$e6}lsds^j8M~Lbpk^zkGiB9i}@}F zUF^kRW3yw14MWJ#39x0VqnP;Nk(k#AOqG){3PVGZWObA}HI+@dV@BU55E8D3X^F_NDFnbc zBdS^%%+L$&45LD^f)gS%G&t@ZZI~Gm5*Y!3aW+Z=1&D&eC2KW$Er?|X1K05Uk`)0K zBr?rBpjI6MduMil0eR}oP(x4DGIq4gCRqJ@*m!DJ%r4U*0Ust$32OgP+nh17Fa+Zu zRjrSJ_>8utwh3lgqG|82q<|-A0&Wn(E*NC_v}$HB2r%0csQnk1z1K5%UNvYL)o>2A z^l%zxX5ia{Bg3I1j3m=@c|>rs8h%W)QO2SfG;m=I4zYlYwSZ=$QeZ|CoGjYtd&nFx z1!iu8p=;KRTgVe$tY@NIvlrbO({kqPOAOQwP%-bE$!e^^Lqs0{%`cH0YmUHAS|VAR?+t z*0Pm@xl;!;i(}CnhK9GajSJUCpb?9#__%yZjPLYpy34x=j=HO8G4I0eEiq+_EM4}r=etO-n>WIbEWgussp!#+H< zHuH;;QAYK_h15=vixEw|O#PYSr|Q{0*^j=ZoHk+`b{O3sE3oz!wTd)`hp;nP_l&!! zb!sGAIgP@3y%Fd2U`Oa_)bFGUAOJjn$Fr5c=hKkCi(FDBsFVpRWr9kXpi(BNlnGjr z87F0eN|~TiCa9DNDrJI7nV?c8sFVpRWr9kXpfsT5UQWeN(#t<_FZ)cs{8Rg~&-Kec z`7fUxP(Fj8e3n7kJcP1&3T5*c%H}zg&4VbLCn05mN*SnsRsK>~3YYxCFD1;JCx~Rw zqyzUYlR@Q4K|z;a`K6pJX+e^Tg1DnerLsYj3WK=axBXHqvO$yH1##NvektJ=9rJ^@ z{c)wzL6c|@7xB_B<-A3!ydW;*ajAUJq}(7*eZw!sA|EslP(2u48}Vatu6*}p@7jMK{6>qgwY}=H0eSR zcM>qhSaduu!f25cnshdZy9gNXS+oid;tm5wi>%P3Gl21CsT5G5>U!xabPRb^x+BQz z%8+MF-1AGZWCE;epOt2n33SUZ#Zn-MeKfJO*Z}8J8E_bc@ueXI(5K4)UBPsepR|gm z7kQvbWfXx`RiG{vC{+cjSAl|7pvDy_dj%#@f#FnOUgeCiyrq`40P1HyF#l-?+TUP6)L?eG)8(?sPwMTGT-v8_(^*CC+=mR$(Mg> zU-r4alp!j;D^$uy`p5Z5$Pj&sBuI-4(bxeIr7}cg-P>-LW>O1*emWFL(w8bH1@K)to;wb(IQ1O z_M$sC9ynU0h{i?$#{;D@Dq}CWbF+b?MT%(bdEj`iRCZ?US$A$NaI{DfjSY9_Mgm8R z6w%l-z%i&)KB!Q&qjVKIdg@De1o@R^$TKERm1Y90&P*uHDidf=X@Ma2SVL*C89M9B zpu<4CP#Q!)J+}T!Fe*U=$UYP6Y;5 z&J5+{Y*kjqnoAkG}zSw7k<8;_QcSSyZf%jQ=8UCL69 zsFWiry+u@di>Ub(q|#eN@gh6CKuyXK6<+Wty+xG0`Br+1C|(?nH%3Zt5tZH|D!oNi SdW)#^7SZ=_%J{SE!2btPrJpkZ diff --git a/contrib/macdeploy/fancy.plist b/contrib/macdeploy/fancy.plist deleted file mode 100644 index 08c2a06fcc..0000000000 --- a/contrib/macdeploy/fancy.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - window_bounds - - 300 - 300 - 800 - 620 - - background_picture - background.png - icon_size - 96 - applications_symlink - - items_position - - Applications - - 370 - 156 - - NovaCoin-Qt.app - - 128 - 156 - - - - diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus deleted file mode 100644 index 7981eca402..0000000000 --- a/contrib/macdeploy/macdeployqtplus +++ /dev/null @@ -1,758 +0,0 @@ -#!/usr/bin/env python - -# -# Copyright (C) 2011 Patrick "p2k" Schneider -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -import subprocess, sys, re, os, shutil, stat, os.path -from string import Template -from time import sleep -from argparse import ArgumentParser - -# This is ported from the original macdeployqt with modifications - -class FrameworkInfo(object): - def __init__(self): - self.frameworkDirectory = "" - self.frameworkName = "" - self.frameworkPath = "" - self.binaryDirectory = "" - self.binaryName = "" - self.binaryPath = "" - self.version = "" - self.installName = "" - self.deployedInstallName = "" - self.sourceFilePath = "" - self.destinationDirectory = "" - self.sourceResourcesDirectory = "" - self.destinationResourcesDirectory = "" - - def __eq__(self, other): - if self.__class__ == other.__class__: - return self.__dict__ == other.__dict__ - else: - return False - - def __str__(self): - return """ Framework name: %s - Framework directory: %s - Framework path: %s - Binary name: %s - Binary directory: %s - Binary path: %s - Version: %s - Install name: %s - Deployed install name: %s - Source file Path: %s - Deployed Directory (relative to bundle): %s -""" % (self.frameworkName, - self.frameworkDirectory, - self.frameworkPath, - self.binaryName, - self.binaryDirectory, - self.binaryPath, - self.version, - self.installName, - self.deployedInstallName, - self.sourceFilePath, - self.destinationDirectory) - - def isDylib(self): - return self.frameworkName.endswith(".dylib") - - def isQtFramework(self): - if self.isDylib(): - return self.frameworkName.startswith("libQt") - else: - return self.frameworkName.startswith("Qt") - - reOLine = re.compile(r'^(.+) \(compatibility version [0-9.]+, current version [0-9.]+\)$') - bundleFrameworkDirectory = "Contents/Frameworks" - bundleBinaryDirectory = "Contents/MacOS" - - @classmethod - def fromOtoolLibraryLine(cls, line): - # Note: line must be trimmed - if line == "": - return None - - # Don't deploy system libraries (exception for libQtuitools and libQtlucene). - if line.startswith("/System/Library/") or line.startswith("@executable_path") or (line.startswith("/usr/lib/") and "libQt" not in line): - return None - - m = cls.reOLine.match(line) - if m is None: - raise RuntimeError("otool line could not be parsed: " + line) - - path = m.group(1) - - info = cls() - info.sourceFilePath = path - info.installName = path - - if path.endswith(".dylib"): - dirname, filename = os.path.split(path) - info.frameworkName = filename - info.frameworkDirectory = dirname - info.frameworkPath = path - - info.binaryDirectory = dirname - info.binaryName = filename - info.binaryPath = path - info.version = "-" - - info.installName = path - info.deployedInstallName = "@executable_path/../Frameworks/" + info.binaryName - info.sourceFilePath = path - info.destinationDirectory = cls.bundleFrameworkDirectory - else: - parts = path.split("/") - i = 0 - # Search for the .framework directory - for part in parts: - if part.endswith(".framework"): - break - i += 1 - if i == len(parts): - raise RuntimeError("Could not find .framework or .dylib in otool line: " + line) - - info.frameworkName = parts[i] - info.frameworkDirectory = "/".join(parts[:i]) - info.frameworkPath = os.path.join(info.frameworkDirectory, info.frameworkName) - - info.binaryName = parts[i+3] - info.binaryDirectory = "/".join(parts[i+1:i+3]) - info.binaryPath = os.path.join(info.binaryDirectory, info.binaryName) - info.version = parts[i+2] - - info.deployedInstallName = "@executable_path/../Frameworks/" + os.path.join(info.frameworkName, info.binaryPath) - info.destinationDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, info.binaryDirectory) - - info.sourceResourcesDirectory = os.path.join(info.frameworkPath, "Resources") - info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources") - - return info - -class ApplicationBundleInfo(object): - def __init__(self, path): - self.path = path - appName = os.path.splitext(os.path.basename(path))[0] - self.binaryPath = os.path.join(path, "Contents", "MacOS", appName) - if not os.path.exists(self.binaryPath): - raise RuntimeError("Could not find bundle binary for " + path) - self.resourcesPath = os.path.join(path, "Contents", "Resources") - self.pluginPath = os.path.join(path, "Contents", "PlugIns") - -class DeploymentInfo(object): - def __init__(self): - self.qtPath = None - self.pluginPath = None - self.deployedFrameworks = [] - - def detectQtPath(self, frameworkDirectory): - parentDir = os.path.dirname(frameworkDirectory) - if os.path.exists(os.path.join(parentDir, "translations")): - # Classic layout, e.g. "/usr/local/Trolltech/Qt-4.x.x" - self.qtPath = parentDir - elif os.path.exists(os.path.join(parentDir, "share", "qt4", "translations")): - # MacPorts layout, e.g. "/opt/local/share/qt4" - self.qtPath = os.path.join(parentDir, "share", "qt4") - elif os.path.exists(os.path.join(os.path.dirname(parentDir), "share", "qt4", "translations")): - # Newer Macports layout - self.qtPath = os.path.join(os.path.dirname(parentDir), "share", "qt4") - else: - self.qtPath = os.getenv("QTDIR", None) - - if self.qtPath is not None: - pluginPath = os.path.join(self.qtPath, "plugins") - if os.path.exists(pluginPath): - self.pluginPath = pluginPath - - def usesFramework(self, name): - nameDot = "%s." % name - libNameDot = "lib%s." % name - for framework in self.deployedFrameworks: - if framework.endswith(".framework"): - if framework.startswith(nameDot): - return True - elif framework.endswith(".dylib"): - if framework.startswith(libNameDot): - return True - return False - -def getFrameworks(binaryPath, verbose): - if verbose >= 3: - print "Inspecting with otool: " + binaryPath - otool = subprocess.Popen(["otool", "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - o_stdout, o_stderr = otool.communicate() - if otool.returncode != 0: - if verbose >= 1: - sys.stderr.write(o_stderr) - sys.stderr.flush() - raise RuntimeError("otool failed with return code %d" % otool.returncode) - - otoolLines = o_stdout.split("\n") - otoolLines.pop(0) # First line is the inspected binary - if ".framework" in binaryPath or binaryPath.endswith(".dylib"): - otoolLines.pop(0) # Frameworks and dylibs list themselves as a dependency. - - libraries = [] - for line in otoolLines: - info = FrameworkInfo.fromOtoolLibraryLine(line.strip()) - if info is not None: - if verbose >= 3: - print "Found framework:" - print info - libraries.append(info) - - return libraries - -def runInstallNameTool(action, *args): - subprocess.check_call(["install_name_tool", "-"+action] + list(args)) - -def changeInstallName(oldName, newName, binaryPath, verbose): - if verbose >= 3: - print "Using install_name_tool:" - print " in", binaryPath - print " change reference", oldName - print " to", newName - runInstallNameTool("change", oldName, newName, binaryPath) - -def changeIdentification(id, binaryPath, verbose): - if verbose >= 3: - print "Using install_name_tool:" - print " change identification in", binaryPath - print " to", id - runInstallNameTool("id", id, binaryPath) - -def runStrip(binaryPath, verbose): - if verbose >= 3: - print "Using strip:" - print " stripped", binaryPath - subprocess.check_call(["strip", "-x", binaryPath]) - -def copyFramework(framework, path, verbose): - if framework.sourceFilePath.startswith("Qt"): - #standard place for Nokia Qt installer's frameworks - fromPath = "/Library/Frameworks/" + framework.sourceFilePath - else: - fromPath = framework.sourceFilePath - - toDir = os.path.join(path, framework.destinationDirectory) - toPath = os.path.join(toDir, framework.binaryName) - - if not os.path.exists(fromPath): - raise RuntimeError("No file at " + fromPath) - - if os.path.exists(toPath): - return None # Already there - - if not os.path.exists(toDir): - os.makedirs(toDir) - - shutil.copy2(fromPath, toPath) - if verbose >= 3: - print "Copied:", fromPath - print " to:", toPath - - permissions = os.stat(toPath) - if not permissions.st_mode & stat.S_IWRITE: - os.chmod(toPath, permissions.st_mode | stat.S_IWRITE) - - if not framework.isDylib(): # Copy resources for real frameworks - fromResourcesDir = framework.sourceResourcesDirectory - if os.path.exists(fromResourcesDir): - toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory) - shutil.copytree(fromResourcesDir, toResourcesDir) - if verbose >= 3: - print "Copied resources:", fromResourcesDir - print " to:", toResourcesDir - elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout) - qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib") - qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib") - if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath): - shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath) - if verbose >= 3: - print "Copied for libQtGui:", qtMenuNibSourcePath - print " to:", qtMenuNibDestinationPath - - return toPath - -def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploymentInfo=None): - if deploymentInfo is None: - deploymentInfo = DeploymentInfo() - - while len(frameworks) > 0: - framework = frameworks.pop(0) - deploymentInfo.deployedFrameworks.append(framework.frameworkName) - - if verbose >= 2: - print "Processing", framework.frameworkName, "..." - - # Get the Qt path from one of the Qt frameworks - if deploymentInfo.qtPath is None and framework.isQtFramework(): - deploymentInfo.detectQtPath(framework.frameworkDirectory) - - if framework.installName.startswith("@executable_path"): - if verbose >= 2: - print framework.frameworkName, "already deployed, skipping." - continue - - # install_name_tool the new id into the binary - changeInstallName(framework.installName, framework.deployedInstallName, binaryPath, verbose) - - # Copy farmework to app bundle. - deployedBinaryPath = copyFramework(framework, bundlePath, verbose) - # Skip the rest if already was deployed. - if deployedBinaryPath is None: - continue - - if strip: - runStrip(deployedBinaryPath, verbose) - - # install_name_tool it a new id. - changeIdentification(framework.deployedInstallName, deployedBinaryPath, verbose) - # Check for framework dependencies - dependencies = getFrameworks(deployedBinaryPath, verbose) - - for dependency in dependencies: - changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath, verbose) - - # Deploy framework if necessary. - if dependency.frameworkName not in deploymentInfo.deployedFrameworks and dependency not in frameworks: - frameworks.append(dependency) - - return deploymentInfo - -def deployFrameworksForAppBundle(applicationBundle, strip, verbose): - frameworks = getFrameworks(applicationBundle.binaryPath, verbose) - if len(frameworks) == 0 and verbose >= 1: - print "Warning: Could not find any external frameworks to deploy in %s." % (applicationBundle.path) - return DeploymentInfo() - else: - return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) - -def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose): - # Lookup available plugins, exclude unneeded - plugins = [] - for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath): - pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath) - if pluginDirectory == "designer": - # Skip designer plugins - continue - elif pluginDirectory == "phonon" or pluginDirectory == "phonon_backend": - # Deploy the phonon plugins only if phonon is in use - if not deploymentInfo.usesFramework("phonon"): - continue - elif pluginDirectory == "sqldrivers": - # Deploy the sql plugins only if QtSql is in use - if not deploymentInfo.usesFramework("QtSql"): - continue - elif pluginDirectory == "script": - # Deploy the script plugins only if QtScript is in use - if not deploymentInfo.usesFramework("QtScript"): - continue - elif pluginDirectory == "qmltooling": - # Deploy the qml plugins only if QtDeclarative is in use - if not deploymentInfo.usesFramework("QtDeclarative"): - continue - elif pluginDirectory == "bearer": - # Deploy the bearer plugins only if QtNetwork is in use - if not deploymentInfo.usesFramework("QtNetwork"): - continue - - for pluginName in filenames: - pluginPath = os.path.join(pluginDirectory, pluginName) - if pluginName.endswith("_debug.dylib"): - # Skip debug plugins - continue - elif pluginPath == "imageformats/libqsvg.dylib" or pluginPath == "iconengines/libqsvgicon.dylib": - # Deploy the svg plugins only if QtSvg is in use - if not deploymentInfo.usesFramework("QtSvg"): - continue - elif pluginPath == "accessible/libqtaccessiblecompatwidgets.dylib": - # Deploy accessibility for Qt3Support only if the Qt3Support is in use - if not deploymentInfo.usesFramework("Qt3Support"): - continue - elif pluginPath == "graphicssystems/libqglgraphicssystem.dylib": - # Deploy the opengl graphicssystem plugin only if QtOpenGL is in use - if not deploymentInfo.usesFramework("QtOpenGL"): - continue - - plugins.append((pluginDirectory, pluginName)) - - for pluginDirectory, pluginName in plugins: - if verbose >= 2: - print "Processing plugin", os.path.join(pluginDirectory, pluginName), "..." - - sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName) - destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory) - if not os.path.exists(destinationDirectory): - os.makedirs(destinationDirectory) - - destinationPath = os.path.join(destinationDirectory, pluginName) - shutil.copy2(sourcePath, destinationPath) - if verbose >= 3: - print "Copied:", sourcePath - print " to:", destinationPath - - if strip: - runStrip(destinationPath, verbose) - - dependencies = getFrameworks(destinationPath, verbose) - - for dependency in dependencies: - changeInstallName(dependency.installName, dependency.deployedInstallName, destinationPath, verbose) - - # Deploy framework if necessary. - if dependency.frameworkName not in deploymentInfo.deployedFrameworks: - deployFrameworks([dependency], appBundleInfo.path, destinationPath, strip, verbose, deploymentInfo) - -qt_conf="""[Paths] -translations=Resources -plugins=PlugIns -""" - -ap = ArgumentParser(description="""Improved version of macdeployqt. - -Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file. -Note, that the "dist" folder will be deleted before deploying on each run. - -Optionally, Qt translation files (.qm) and additional resources can be added to the bundle.""") - -ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed") -ap.add_argument("-verbose", type=int, nargs=1, default=[1], metavar="<0-3>", help="0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug") -ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment") -ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries") -ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image; if basename is not specified, a camel-cased version of the app name is used") -ap.add_argument("-fancy", nargs=1, metavar="plist", default=[], help="make a fancy looking disk image using the given plist file with instructions; requires -dmg to work") -ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's ressources; the language list must be separated with commas, not with whitespace") -ap.add_argument("-add-resources", nargs="+", metavar="path", default=[], help="list of additional files or folders to be copied into the bundle's resources; must be the last argument") - -config = ap.parse_args() - -verbose = config.verbose[0] - -# ------------------------------------------------ - -app_bundle = config.app_bundle[0] - -if not os.path.exists(app_bundle): - if verbose >= 1: - sys.stderr.write("Error: Could not find app bundle \"%s\"\n" % (app_bundle)) - sys.exit(1) - -app_bundle_name = os.path.splitext(os.path.basename(app_bundle))[0] - -# ------------------------------------------------ - -for p in config.add_resources: - if verbose >= 3: - print "Checking for \"%s\"..." % p - if not os.path.exists(p): - if verbose >= 1: - sys.stderr.write("Error: Could not find additional resource file \"%s\"\n" % (p)) - sys.exit(1) - -# ------------------------------------------------ - -if len(config.fancy) == 1: - if verbose >= 3: - print "Fancy: Importing plistlib..." - try: - import plistlib - except ImportError: - if verbose >= 1: - sys.stderr.write("Error: Could not import plistlib which is required for fancy disk images.\n") - sys.exit(1) - - if verbose >= 3: - print "Fancy: Importing appscript..." - try: - import appscript - except ImportError: - if verbose >= 1: - sys.stderr.write("Error: Could not import appscript which is required for fancy disk images.\n") - sys.stderr.write("Please install it e.g. with \"sudo easy_install appscript\".\n") - sys.exit(1) - - p = config.fancy[0] - if verbose >= 3: - print "Fancy: Loading \"%s\"..." % p - if not os.path.exists(p): - if verbose >= 1: - sys.stderr.write("Error: Could not find fancy disk image plist at \"%s\"\n" % (p)) - sys.exit(1) - - try: - fancy = plistlib.readPlist(p) - except: - if verbose >= 1: - sys.stderr.write("Error: Could not parse fancy disk image plist at \"%s\"\n" % (p)) - sys.exit(1) - - try: - assert not fancy.has_key("window_bounds") or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4) - assert not fancy.has_key("background_picture") or isinstance(fancy["background_picture"], str) - assert not fancy.has_key("icon_size") or isinstance(fancy["icon_size"], int) - assert not fancy.has_key("applications_symlink") or isinstance(fancy["applications_symlink"], bool) - if fancy.has_key("items_position"): - assert isinstance(fancy["items_position"], dict) - for key, value in fancy["items_position"].iteritems(): - assert isinstance(value, list) and len(value) == 2 and isinstance(value[0], int) and isinstance(value[1], int) - except: - if verbose >= 1: - sys.stderr.write("Error: Bad format of fancy disk image plist at \"%s\"\n" % (p)) - sys.exit(1) - - if fancy.has_key("background_picture"): - bp = fancy["background_picture"] - if verbose >= 3: - print "Fancy: Resolving background picture \"%s\"..." % bp - if not os.path.exists(bp): - bp = os.path.join(os.path.dirname(p), bp) - if not os.path.exists(bp): - if verbose >= 1: - sys.stderr.write("Error: Could not find background picture at \"%s\" or \"%s\"\n" % (fancy["background_picture"], bp)) - sys.exit(1) - else: - fancy["background_picture"] = bp -else: - fancy = None - -# ------------------------------------------------ - -if os.path.exists("dist"): - if verbose >= 2: - print "+ Removing old dist folder +" - - shutil.rmtree("dist") - -# ------------------------------------------------ - -target = os.path.join("dist", app_bundle) - -if verbose >= 2: - print "+ Copying source bundle +" -if verbose >= 3: - print app_bundle, "->", target - -os.mkdir("dist") -shutil.copytree(app_bundle, target) - -applicationBundle = ApplicationBundleInfo(target) - -# ------------------------------------------------ - -if verbose >= 2: - print "+ Deploying frameworks +" - -try: - deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose) - if deploymentInfo.qtPath is None: - deploymentInfo.qtPath = os.getenv("QTDIR", None) - if deploymentInfo.qtPath is None: - if verbose >= 1: - sys.stderr.write("Warning: Could not detect Qt's path, skipping plugin deployment!\n") - config.plugins = False -except RuntimeError as e: - if verbose >= 1: - sys.stderr.write("Error: %s\n" % str(e)) - sys.exit(ret) - -# ------------------------------------------------ - -if config.plugins: - if verbose >= 2: - print "+ Deploying plugins +" - - try: - deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose) - except RuntimeError as e: - if verbose >= 1: - sys.stderr.write("Error: %s\n" % str(e)) - sys.exit(ret) - -# ------------------------------------------------ - -if len(config.add_qt_tr) == 0: - add_qt_tr = [] -else: - qt_tr_dir = os.path.join(deploymentInfo.qtPath, "translations") - add_qt_tr = ["qt_%s.qm" % lng for lng in config.add_qt_tr[0].split(",")] - for lng_file in add_qt_tr: - p = os.path.join(qt_tr_dir, lng_file) - if verbose >= 3: - print "Checking for \"%s\"..." % p - if not os.path.exists(p): - if verbose >= 1: - sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file)) - sys.exit(1) - -# ------------------------------------------------ - -if verbose >= 2: - print "+ Installing qt.conf +" - -f = open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") -f.write(qt_conf) -f.close() - -# ------------------------------------------------ - -if len(add_qt_tr) > 0 and verbose >= 2: - print "+ Adding Qt translations +" - -for lng_file in add_qt_tr: - if verbose >= 3: - print os.path.join(qt_tr_dir, lng_file), "->", os.path.join(applicationBundle.resourcesPath, lng_file) - shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(applicationBundle.resourcesPath, lng_file)) - -# ------------------------------------------------ - -if len(config.add_resources) > 0 and verbose >= 2: - print "+ Adding additional resources +" - -for p in config.add_resources: - t = os.path.join(applicationBundle.resourcesPath, os.path.basename(p)) - if verbose >= 3: - print p, "->", t - if os.path.isdir(p): - shutil.copytree(p, t) - else: - shutil.copy2(p, t) - -# ------------------------------------------------ - -if config.dmg is not None: - def runHDIUtil(verb, image_basename, **kwargs): - hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"] - if kwargs.has_key("capture_stdout"): - del kwargs["capture_stdout"] - run = subprocess.check_output - else: - if verbose < 2: - hdiutil_args.append("-quiet") - elif verbose >= 3: - hdiutil_args.append("-verbose") - run = subprocess.check_call - - for key, value in kwargs.iteritems(): - hdiutil_args.append("-" + key) - if not value is True: - hdiutil_args.append(str(value)) - - return run(hdiutil_args) - - if verbose >= 2: - if fancy is None: - print "+ Creating .dmg disk image +" - else: - print "+ Preparing .dmg disk image +" - - if config.dmg != "": - dmg_name = config.dmg - else: - spl = app_bundle_name.split(" ") - dmg_name = spl[0] + "".join(p.capitalize() for p in spl[1:]) - - if fancy is None: - try: - runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname=app_bundle_name, ov=True) - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - else: - if verbose >= 3: - print "Determining size of \"dist\"..." - size = 0 - for path, dirs, files in os.walk("dist"): - for file in files: - size += os.path.getsize(os.path.join(path, file)) - size += int(size * 0.1) - - if verbose >= 3: - print "Creating temp image for modification..." - try: - runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=app_bundle_name, ov=True) - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - - if verbose >= 3: - print "Attaching temp image..." - try: - output = runHDIUtil("attach", dmg_name + ".temp", readwrite=True, noverify=True, noautoopen=True, capture_stdout=True) - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - - m = re.search("/Volumes/(.+$)", output) - disk_root = m.group(0) - disk_name = m.group(1) - - if verbose >= 2: - print "+ Applying fancy settings +" - - if fancy.has_key("background_picture"): - bg_path = os.path.join(disk_root, os.path.basename(fancy["background_picture"])) - if verbose >= 3: - print fancy["background_picture"], "->", bg_path - shutil.copy2(fancy["background_picture"], bg_path) - else: - bg_path = None - - if fancy.get("applications_symlink", False): - os.symlink("/Applications", os.path.join(disk_root, "Applications")) - - finder = appscript.app("Finder") - disk = finder.disks[disk_name] - disk.open() - window = disk.container_window - window.current_view.set(appscript.k.icon_view) - window.toolbar_visible.set(False) - window.statusbar_visible.set(False) - if fancy.has_key("window_bounds"): - window.bounds.set(fancy["window_bounds"]) - view_options = window.icon_view_options - view_options.arrangement.set(appscript.k.not_arranged) - if fancy.has_key("icon_size"): - view_options.icon_size.set(fancy["icon_size"]) - if bg_path is not None: - view_options.background_picture.set(disk.files[os.path.basename(bg_path)]) - if fancy.has_key("items_position"): - for name, position in fancy["items_position"].iteritems(): - window.items[name].position.set(position) - disk.close() - if bg_path is not None: - subprocess.call(["SetFile", "-a", "V", bg_path]) - disk.update(registering_applications=False) - sleep(2) - disk.eject() - - if verbose >= 2: - print "+ Finalizing .dmg disk image +" - - try: - runHDIUtil("convert", dmg_name + ".temp", format="UDBZ", o=dmg_name + ".dmg", ov=True) - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - - os.unlink(dmg_name + ".temp.dmg") - -# ------------------------------------------------ - -if verbose >= 2: - print "+ Done +" - -sys.exit(0) diff --git a/contrib/macdeploy/notes.txt b/contrib/macdeploy/notes.txt deleted file mode 100644 index 9b592fc955..0000000000 --- a/contrib/macdeploy/notes.txt +++ /dev/null @@ -1,26 +0,0 @@ - -macdeployqtplus works best on OS X Lion, for Snow Leopard you'd need to install -Python 2.7 and make it your default Python installation. - -You will need the appscript package for the fancy disk image creation to work. -Install it by invoking "sudo easy_install appscript". - -Ths script should be invoked in the target directory like this: -$source_dir/contrib/macdeploy/macdeployqtplus NovaCoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy $source_dir/contrib/macdeploy/fancy.plist -verbose 2 - -During the process, the disk image window will pop up briefly where the fancy -settings are applied. This is normal, please do not interfere. - -You can also set up Qt Creator for invoking the script. For this, go to the -"Projects" tab on the left side, switch to "Run Settings" above and add a -deploy configuration. Next add a deploy step choosing "Custom Process Step". -Fill in the following. - -Enable custom process step: [x] -Command: %{sourceDir}/contrib/macdeploy/macdeployqtplus -Working directory: %{buildDir} -Command arguments: NovaCoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist -verbose 2 - -After that you can start the deployment process through the menu with -Build -> Deploy Project "novacoin-qt" - From 4ec4bb2983c4c610fb2ffca879596dc47423af59 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Tue, 3 Oct 2017 00:12:42 -0700 Subject: [PATCH 016/166] Backup wallet refactor (#660) - Make backup.cpp/h and move neccessary code around + add headers where needed - Change backupwallet rpc to do wallet and config backup - Remove execute backupwallet - Modify backup wallet to iunclude config - Remove no longer needed backupWallet in walletmodel --- gridcoinresearch.pro | 2 + src/Makefile.include.objs | 1 + src/backup.cpp | 133 ++++++++++++++++++++++++++++++++++++++ src/backup.h | 15 +++++ src/db.h | 2 - src/main.cpp | 41 +----------- src/main.h | 4 -- src/qt/bitcoingui.cpp | 17 +++-- src/qt/walletmodel.cpp | 6 -- src/qt/walletmodel.h | 2 - src/rpcblockchain.cpp | 12 +--- src/rpcwallet.cpp | 18 +++--- src/walletdb.cpp | 71 -------------------- 13 files changed, 175 insertions(+), 149 deletions(-) create mode 100644 src/backup.cpp create mode 100644 src/backup.h diff --git a/gridcoinresearch.pro b/gridcoinresearch.pro index 6ebba2c751..52282ce9af 100755 --- a/gridcoinresearch.pro +++ b/gridcoinresearch.pro @@ -271,6 +271,7 @@ HEADERS += src/qt/bitcoingui.h \ src/cpid.h \ src/upgrader.h \ src/boinc.h \ + src/backup.h \ src/appcache.h @@ -351,6 +352,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/upgrader.cpp \ src/boinc.cpp \ src/allocators.cpp \ + src/backup.cpp \ src/appcache.cpp ## diff --git a/src/Makefile.include.objs b/src/Makefile.include.objs index 69e593e0d9..8d4aa43755 100755 --- a/src/Makefile.include.objs +++ b/src/Makefile.include.objs @@ -39,4 +39,5 @@ OBJS= \ obj/beacon.o \ obj/boinc.o \ obj/allocators.o \ + obj/backup.o \ obj/appcache.o diff --git a/src/backup.cpp b/src/backup.cpp new file mode 100644 index 0000000000..2041f3182e --- /dev/null +++ b/src/backup.cpp @@ -0,0 +1,133 @@ +// Backup related functions are placed here to keep vital sections of +// code contained while maintaining clean code. + +#include "walletdb.h" +#include "wallet.h" +#include "util.h" + +#include +#include + +#include +#include + +boost::filesystem::path GetBackupPath(); + +using namespace boost; + +boost::filesystem::path GetBackupPath() +{ + filesystem::path defaultDir = GetDataDir() / "walletbackups"; + return GetArg("-backupdir", defaultDir.string()); +} + +std::string GetBackupFilename(const std::string& basename, const std::string& suffix = "") +{ + time_t biTime; + struct tm * blTime; + time (&biTime); + blTime = localtime(&biTime); + char boTime[200]; + strftime(boTime, sizeof(boTime), "%Y-%m-%dT%H-%M-%S", blTime); + std::string sBackupFilename; + filesystem::path rpath; + sBackupFilename = basename + "-" + std::string(boTime); + if (!suffix.empty()) + sBackupFilename = sBackupFilename + "-" + suffix; + rpath = GetBackupPath() / sBackupFilename; + return rpath.string(); +} + +bool BackupConfigFile(const std::string& strDest) +{ + // Check to see if there is a parent_path in strDest to support custom locations by ui - bug fix + + filesystem::path ConfigSource = GetDataDir() / "gridcoinresearch.conf"; + filesystem::path ConfigTarget = strDest; + filesystem::create_directories(ConfigTarget.parent_path()); + try + { + #if BOOST_VERSION >= 104000 + filesystem::copy_file(ConfigSource, ConfigTarget, filesystem::copy_option::overwrite_if_exists); + #else + filesystem::copy_file(ConfigSource, ConfigTarget); + #endif + printf("BackupConfigFile: Copied gridcoinresearch.conf to %s\n", ConfigTarget.string().c_str()); + return true; + } + catch(const filesystem::filesystem_error &e) + { + printf("BackupConfigFile: Error copying gridcoinresearch.conf to %s - %s\n", ConfigTarget.string().c_str(), e.what()); + return false; + } + return false; +} + +bool BackupWallet(const CWallet& wallet, const std::string& strDest) +{ + if (!wallet.fFileBacked) + return false; + while (!fShutdown) + { + { + LOCK(bitdb.cs_db); + if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0) + { + // Flush log data to the dat file + bitdb.CloseDb(wallet.strWalletFile); + bitdb.CheckpointLSN(wallet.strWalletFile); + bitdb.mapFileUseCount.erase(wallet.strWalletFile); + + // Copy wallet.dat + filesystem::path WalletSource = GetDataDir() / wallet.strWalletFile; + filesystem::path WalletTarget = strDest; + filesystem::create_directories(WalletTarget.parent_path()); + if (filesystem::is_directory(WalletTarget)) + WalletTarget /= wallet.strWalletFile; + try + { + #if BOOST_VERSION >= 104000 + filesystem::copy_file(WalletSource, WalletTarget, filesystem::copy_option::overwrite_if_exists); + #else + filesystem::copy_file(WalletSource, WalletTarget); + #endif + printf("BackupWallet: Copied wallet.dat to %s\r\n", WalletTarget.string().c_str()); + return true; + } + catch(const filesystem::filesystem_error &e) { + printf("BackupWallet: Error copying wallet.dat to %s - %s\r\n", WalletTarget.string().c_str(), e.what()); + return false; + } + } + } + MilliSleep(100); + } + return false; +} + +bool BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors) +{ + if (wallet.IsLocked() || fWalletUnlockStakingOnly) + { + sErrors = "Wallet needs to be fully unlocked to backup private keys. "; + return false; + } + filesystem::path PrivateKeysTarget = GetBackupFilename("keys.dat"); + filesystem::create_directories(PrivateKeysTarget.parent_path()); + sTarget = PrivateKeysTarget.string(); + std::ofstream myBackup; + myBackup.open (PrivateKeysTarget.string().c_str()); + std::string sError; + for(const auto& keyPair : wallet.GetAllPrivateKeys(sError)) + { + if (!sError.empty()) + { + sErrors = sError; + return false; + } + myBackup << "Address: " << keyPair.first.ToString() << ", Secret: " << keyPair.second.ToString() << std::endl; + } + printf("BackupPrivateKeys: Backup made to %s\r\n", PrivateKeysTarget.string().c_str()); + myBackup.close(); + return true; +} diff --git a/src/backup.h b/src/backup.h new file mode 100644 index 0000000000..9860921e24 --- /dev/null +++ b/src/backup.h @@ -0,0 +1,15 @@ +#ifndef BACKUP_H +#define BACKUP_H + +// Backup related functions +#include + +class CWallet; + +std::string GetBackupFilename(const std::string& basename, const std::string& suffix = ""); +bool BackupConfigFile(const std::string& strDest); +bool BackupWallet(const CWallet& wallet, const std::string& strDest); +extern bool BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors); +extern bool BackupWallet(const CWallet& wallet, const std::string& strDest); + +#endif // BACKUP_H diff --git a/src/db.h b/src/db.h index 3a2de20e1b..623dbfd369 100644 --- a/src/db.h +++ b/src/db.h @@ -27,8 +27,6 @@ class CWalletTx; extern unsigned int nWalletDBUpdated; void ThreadFlushWalletDB(void* parg); -bool BackupWallet(const CWallet& wallet, const std::string& strDest); - class CDBEnv { diff --git a/src/main.cpp b/src/main.cpp index 55fad59e24..60f0cf0982 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,7 @@ #include "boinc.h" #include "beacon.h" #include "miner.h" +#include "backup.h" #include #include @@ -196,8 +197,6 @@ std::string msMasterProjectPublicKey = "049ac003b3318d9fe28b2830f6a95a2624ce2a6 std::string msMasterMessagePrivateKey = "308201130201010420fbd45ffb02ff05a3322c0d77e1e7aea264866c24e81e5ab6a8e150666b4dc6d8a081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a144034200044b2938fbc38071f24bede21e838a0758a52a0085f2e034e7f971df445436a252467f692ec9c5ba7e5eaa898ab99cbd9949496f7e3cafbf56304b1cc2e5bdf06e"; std::string msMasterMessagePublicKey = "044b2938fbc38071f24bede21e838a0758a52a0085f2e034e7f971df445436a252467f692ec9c5ba7e5eaa898ab99cbd9949496f7e3cafbf56304b1cc2e5bdf06e"; -bool BackupWallet(const CWallet& wallet, const std::string& strDest); - std::string YesNo(bool bin); int64_t GetMaximumBoincSubsidy(int64_t nTime); @@ -9035,44 +9034,6 @@ bool StrLessThanReferenceHash(std::string rh) return (uADH < uRef); } -// Generate backup filenames with local date and time with suffix support -std::string GetBackupFilename(const std::string& basename, const std::string& suffix) -{ - time_t biTime; - struct tm * blTime; - time (&biTime); - blTime = localtime(&biTime); - char boTime[200]; - strftime(boTime, sizeof(boTime), "%Y-%m-%dT%H-%M-%S", blTime); - return suffix.empty() - ? basename + "-" + std::string(boTime) - : basename + "-" + std::string(boTime) + "-" + suffix; -} - -// Todo: Make and move to config.cpp/h (ravon) -bool BackupConfigFile(const std::string& strDest) -{ - filesystem::path ConfigTarget = GetDataDir() / "walletbackups" / strDest; - filesystem::create_directories(ConfigTarget.parent_path()); - filesystem::path ConfigSource = GetDataDir() / "gridcoinresearch.conf"; - try - { - #if BOOST_VERSION >= 104000 - filesystem::copy_file(ConfigSource, ConfigTarget, filesystem::copy_option::overwrite_if_exists); - #else - filesystem::copy_file(ConfigSource, ConfigTarget); - #endif - printf("BackupConfigFile: Copied gridcoinresearch.conf to %s\n", ConfigTarget.string().c_str()); - return true; - } - catch(const filesystem::filesystem_error &e) - { - printf("BackupConfigFile: Error copying gridcoinresearch.conf to %s - %s\n", ConfigTarget.string().c_str(), e.what()); - return false; - } - return false; -} - bool IsResearcher(const std::string& cpid) { return cpid.length() == 32; diff --git a/src/main.h b/src/main.h index 1e17e2ef9e..29e4f3dcc1 100755 --- a/src/main.h +++ b/src/main.h @@ -296,10 +296,6 @@ std::string DefaultWalletAddress(); /** (try to) add transaction to memory pool **/ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool* pfMissingInputs); - -std::string GetBackupFilename(const std::string& basename, const std::string& suffix = ""); -bool BackupConfigFile(const std::string& strDest); - bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); StructCPID GetInitializedStructCPID2(const std::string& name, std::map& vRef); bool IsResearcher(const std::string& cpid); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b75fd49a79..b5cb773066 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -50,6 +50,7 @@ #include "block.h" #include "miner.h" #include "main.h" +#include "backup.h" #ifdef Q_OS_MAC #include "macdockiconhandler.h" @@ -772,8 +773,8 @@ void BitcoinGUI::createActions() encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet")); encryptWalletAction->setCheckable(true); - backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); - backupWalletAction->setToolTip(tr("Backup wallet to another location")); + backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet/Config..."), this); + backupWalletAction->setToolTip(tr("Backup wallet/config to another location")); changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this); changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption")); unlockWalletAction = new QAction(QIcon(":/icons/lock_open"), tr("&Unlock Wallet..."), this); @@ -1700,9 +1701,15 @@ void BitcoinGUI::backupWallet() #else QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); #endif - QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)")); - if(!filename.isEmpty()) { - if(!walletModel->backupWallet(filename)) { + QString walletfilename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)")); + if(!walletfilename.isEmpty()) { + if(!BackupWallet(*pwalletMain, FromQString(walletfilename))) { + QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location.")); + } + } + QString configfilename = QFileDialog::getSaveFileName(this, tr("Backup Config"), saveDir, tr("Wallet Config (*.conf)")); + if(!configfilename.isEmpty()) { + if(!BackupConfigFile(FromQString(configfilename))) { QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location.")); } } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 576a88695a..bb38ec5235 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -6,7 +6,6 @@ #include "ui_interface.h" #include "wallet.h" -#include "walletdb.h" // for BackupWallet #include "base58.h" #include "util.h" @@ -352,11 +351,6 @@ bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureStri return retval; } -bool WalletModel::backupWallet(const QString &filename) -{ - return BackupWallet(*wallet, filename.toLocal8Bit().data()); -} - // Handlers for core signals static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet) { diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 8b24de8f1f..881d0cd0af 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -94,8 +94,6 @@ class WalletModel : public QObject // Passphrase only needed when unlocking bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString()); bool changePassphrase(const SecureString &oldPass, const SecureString &newPass); - // Wallet backup - bool backupWallet(const QString &filename); // RAI object for unlocking wallet, returned by requestUnlock() class UnlockContext diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 2ede06fa20..29e0b06da1 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -12,6 +12,7 @@ #include "txdb.h" #include "beacon.h" #include "util.h" +#include "backup.h" #include "appcache.h" #include @@ -24,8 +25,6 @@ using namespace json_spirit; using namespace std; extern std::string YesNo(bool bin); -bool BackupWallet(const CWallet& wallet, const std::string& strDest); -bool BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors); extern double DoubleFromAmount(int64_t amount); std::string PubKeyToAddress(const CScript& scriptPubKey); CBlockIndex* GetHistoricalMagnitude(std::string cpid); @@ -2415,14 +2414,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("Reset",1)); results.push_back(entry); } - else if (sItem == "backupwallet") - { - bool bWalletBackupResults = BackupWallet(*pwalletMain, GetBackupFilename("wallet.dat")); - bool bConfigBackupResults = BackupConfigFile(GetBackupFilename("gridcoinresearch.conf")); - entry.push_back(Pair("Backup wallet success", bWalletBackupResults)); - entry.push_back(Pair("Backup config success", bConfigBackupResults)); - results.push_back(entry); - } else if (sItem == "resendwallettx") { ResendWalletTransactions(true); @@ -2499,7 +2490,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("execute addpoll <days> <question> <answers> <sharetype> <url>", "Add a poll (Requires minimum 100000 GRC balance)")); entry.push_back(Pair("execute advertisebeacon", "Advertise a beacon (Requires wallet to be fully unlocked)")); entry.push_back(Pair("execute askforoutstandingblocks", "Asks nodes for outstanding blocks")); - entry.push_back(Pair("execute backupwallet", "Backup wallet")); entry.push_back(Pair("execute backupprivatekeys", "Backup private keys (Wallet must be fully unlocked")); entry.push_back(Pair("execute beaconreport", "Displays information about current active beacons in the network")); entry.push_back(Pair("execute beaconstatus", "Displays information about your beacon")); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index c93496255e..82c89f6fed 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -10,6 +10,7 @@ #include "init.h" #include "base58.h" #include "util.h" +#include "backup.h" using namespace json_spirit; using namespace std; @@ -1752,16 +1753,17 @@ Value gettransaction(const Array& params, bool fHelp) Value backupwallet(const Array& params, bool fHelp) { - if (fHelp || params.size() != 1) + if (fHelp || params.size() > 0) throw runtime_error( - "backupwallet <destination>\n" - "Safely copies wallet.dat to destination, which can be a directory or a path with filename."); - - string strDest = params[0].get_str(); - if (!BackupWallet(*pwalletMain, strDest)) - throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); + "backupwallet\n" + "Backup your wallet and config files."); - return Value::null; + bool bWalletBackupResults = BackupWallet(*pwalletMain, GetBackupFilename("wallet.dat")); + bool bConfigBackupResults = BackupConfigFile(GetBackupFilename("gridcoinresearch.conf")); + Object ret; + ret.push_back(Pair("Backup wallet success", bWalletBackupResults)); + ret.push_back(Pair("Backup config success", bConfigBackupResults)); + return ret; } diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 9cf2d410e7..3822595443 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -15,8 +15,6 @@ using namespace boost; static uint64_t nAccountingEntryNumber = 0; extern bool fWalletUnlockStakingOnly; -extern bool BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors); -extern bool BackupWallet(const CWallet& wallet, const std::string& strDest); // // CWalletDB @@ -682,75 +680,6 @@ void ThreadFlushWalletDB(void* parg) } } -bool BackupWallet(const CWallet& wallet, const std::string& strDest) -{ - if (!wallet.fFileBacked) - return false; - while (!fShutdown) - { - { - LOCK(bitdb.cs_db); - if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0) - { - // Flush log data to the dat file - bitdb.CloseDb(wallet.strWalletFile); - bitdb.CheckpointLSN(wallet.strWalletFile); - bitdb.mapFileUseCount.erase(wallet.strWalletFile); - - // Copy wallet.dat - Leave strDest support for WalletModel - filesystem::path WalletTarget = GetDataDir() / "walletbackups" / strDest; - filesystem::create_directories(WalletTarget.parent_path()); - filesystem::path WalletSource = GetDataDir() / wallet.strWalletFile; - if (filesystem::is_directory(WalletTarget)) - WalletTarget /= wallet.strWalletFile; - try - { - #if BOOST_VERSION >= 104000 - filesystem::copy_file(WalletSource, WalletTarget, filesystem::copy_option::overwrite_if_exists); - #else - filesystem::copy_file(WalletSource, WalletTarget); - #endif - printf("BackupWallet: Copied wallet.dat to %s\r\n", WalletTarget.string().c_str()); - return true; - } - catch(const filesystem::filesystem_error &e) { - printf("BackupWallet: Error copying wallet.dat to %s - %s\r\n", WalletTarget.string().c_str(), e.what()); - return false; - } - } - } - MilliSleep(100); - } - return false; -} - -bool BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors) -{ - if (wallet.IsLocked() || fWalletUnlockStakingOnly) - { - sErrors = "Wallet needs to be fully unlocked to backup private keys. "; - return false; - } - filesystem::path PrivateKeysTarget = GetDataDir() / "walletbackups" / GetBackupFilename("keys.dat"); - filesystem::create_directories(PrivateKeysTarget.parent_path()); - sTarget = PrivateKeysTarget.string(); - std::ofstream myBackup; - myBackup.open (PrivateKeysTarget.string().c_str()); - std::string sError; - for(const auto& keyPair : wallet.GetAllPrivateKeys(sError)) - { - if (!sError.empty()) - { - sErrors = sError; - return false; - } - myBackup << "Address: " << keyPair.first.ToString() << ", Secret: " << keyPair.second.ToString() << std::endl; - } - printf("BackupPrivateKeys: Backup made to %s\r\n", PrivateKeysTarget.string().c_str()); - myBackup.close(); - return true; -} - // // Try to (very carefully!) recover wallet.dat if there is a problem. // From e7e41a2ac7f7f3239d9dbbdca4b8e6d7005563ba Mon Sep 17 00:00:00 2001 From: Marco Nilsson <denravonska@gmail.com> Date: Tue, 3 Oct 2017 09:15:27 +0200 Subject: [PATCH 017/166] bitcoingui.cpp cleanup (#666) - Clean up VB calls - Remove SQLQuery function - Remove old coin tracking code - Remove ExecuteCode RPC - Remove reboot RPC command and underlying code. "restartclient" is now just "restart". --- src/qt/bitcoingui.cpp | 1115 ++++++++++++------------------ src/qt/bitcoingui.h | 4 - src/qt/transactiondescdialog.cpp | 1 - src/rpcblockchain.cpp | 37 +- src/wallet.cpp | 37 - 5 files changed, 459 insertions(+), 735 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b5cb773066..1f5994cab4 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -98,10 +98,7 @@ extern CWallet* pwalletMain; int ReindexWallet(); -extern int RebootClient(); extern QString ToQstring(std::string s); -extern void qtUpdateConfirm(std::string txid); -extern void qtInsertConfirm(double dAmt, std::string sFrom, std::string sTo, std::string txid); extern void qtSetSessionInfo(std::string defaultgrcaddress, std::string cpid, double magnitude); extern void qtSyncWithDPORNodes(std::string data); extern double qtExecuteGenericFunction(std::string function,std::string data); @@ -136,12 +133,10 @@ extern int UpgradeClient(); extern void CheckForUpgrade(); bool IsConfigFileEmpty(); - -extern void ExecuteCode(); - void HarvestCPIDs(bool cleardata); extern int RestartClient(); extern int ReindexWallet(); +void ReinstantiateGlobalcom(); #ifdef WIN32 QAxObject *globalcom = NULL; @@ -150,8 +145,8 @@ QAxObject *globalwire = NULL; QString ToQstring(std::string s) { - QString str1 = QString::fromUtf8(s.c_str()); - return str1; + QString str1 = QString::fromUtf8(s.c_str()); + return str1; } @@ -167,12 +162,12 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): trayIcon(0), notificator(0), rpcConsole(0), - upgrader(0), + upgrader(0), nWeight(0) { setGeometry(QStyle::alignedRect(Qt::LeftToRight,Qt::AlignCenter,QSize(980,550),qApp->desktop()->availableGeometry())); - + setWindowTitle(tr("Gridcoin") + " " + tr("Wallet")); #ifndef Q_OS_MAC @@ -240,7 +235,7 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): rpcConsole = new RPCConsole(this); connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show())); - upgrader = new UpgradeDialog(this); + upgrader = new UpgradeDialog(this); connect(upgradeAction, SIGNAL(triggered()), upgrader, SLOT(show())); connect(upgradeAction, SIGNAL(triggered()), upgrader, SLOT(upgrade())); connect(downloadAction, SIGNAL(triggered()), upgrader, SLOT(show())); @@ -270,185 +265,122 @@ BitcoinGUI::~BitcoinGUI() int ReindexWallet() { - if (!bGlobalcomInitialized) return 0; - QString sFilename = "GRCRestarter.exe"; - QString sArgument = ""; - QString path = QCoreApplication::applicationDirPath() + "\\" + sFilename; - QProcess p; - if (!fTestNet) - { -#ifdef WIN32 + if (!bGlobalcomInitialized) + return 0; - globalcom->dynamicCall("ReindexWallet()"); -#endif - } - else - { #ifdef WIN32 - globalcom->dynamicCall("ReindexWalletTestNet()"); + globalcom->dynamicCall(fTestNet + ? "ReindexWalletTestNet()" + : "ReindexWallet()"); #endif - } - StartShutdown(); - return 1; -} - + StartShutdown(); + return 1; +} int CreateRestorePoint() { - if (!bGlobalcomInitialized) return 0; + if (!bGlobalcomInitialized) + return 0; - QString sFilename = "GRCRestarter.exe"; - QString sArgument = ""; - QString path = QCoreApplication::applicationDirPath() + "\\" + sFilename; - QProcess p; - - - if (!fTestNet) - { -#ifdef WIN32 - globalcom->dynamicCall("CreateRestorePoint()"); -#endif - } - else - { #ifdef WIN32 - globalcom->dynamicCall("CreateRestorePointTestNet()"); + globalcom->dynamicCall(fTestNet + ? "CreateRestorePointTestNet()" + : "CreateRestorePoint()"); #endif - } - //RestartGridcoin - return 1; + return 1; } - - int DownloadBlocks() { - printf("executing grcrestarter downloadblocks"); - if (!bGlobalcomInitialized) return 0; + printf("Download blocks."); - QString sFilename = "GRCRestarter.exe"; - QString sArgument = ""; - QString path = QCoreApplication::applicationDirPath() + "\\" + sFilename; - QProcess p; + // Instantiate globalcom if not created. + if (!bGlobalcomInitialized) + ReinstantiateGlobalcom(); - #ifdef WIN32 - if (!globalcom) - { - globalcom = new QAxObject("BoincStake.Utilization"); - } - std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; - double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + // If it still isn't created then there's nothing we can do. + if (!bGlobalcomInitialized) + return 0; - globalcom->dynamicCall("DownloadBlocks()"); - StartShutdown(); - #endif +#ifdef WIN32 + std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; + qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + globalcom->dynamicCall("DownloadBlocks()"); + StartShutdown(); +#endif - return 1; + return 1; } int RestartClient() { - if (!bGlobalcomInitialized) return 0; - QString sFilename = "GRCRestarter.exe"; - QString sArgument = ""; - QString path = QCoreApplication::applicationDirPath() + "\\" + sFilename; - QProcess p; - #ifdef WIN32 - globalcom->dynamicCall("RebootClient()"); - #endif - StartShutdown(); - return 1; -} - -void qtUpdateConfirm(std::string txid) -{ - if (!bGlobalcomInitialized) return; - - #if defined(WIN32) && defined(QT_GUI) - QString qsTxid = ToQstring(txid); - QString sResult = globalcom->dynamicCall("UpdateConfirm(Qstring)",qsTxid).toString(); - #endif - -} - - -void qtInsertConfirm(double dAmt, std::string sFrom, std::string sTo, std::string txid) -{ - if (!bGlobalcomInitialized) return; - - #if defined(WIN32) && defined(QT_GUI) - try - { - int result = 0; - std::string Confirm = RoundToString(dAmt,4) + "<COL>" + sFrom + "<COL>" + sTo + "<COL>" + txid; - QString qsConfirm = ToQstring(Confirm); - result = globalcom->dynamicCall("InsertConfirm(Qstring)",qsConfirm).toInt(); - printf("Inserting confirm %s %f",Confirm.c_str(),(double)result); + if (!bGlobalcomInitialized) + return 0; - } - catch(...) - { +#ifdef WIN32 + globalcom->dynamicCall("RebootClient()"); +#endif - } - #endif + StartShutdown(); + return 1; } double qtPushGridcoinDiagnosticData(std::string data) { - if (!bGlobalcomInitialized) return 0; - int result = 0; - #if defined(WIN32) && defined(QT_GUI) - QString qsData = ToQstring(data); - result = globalcom->dynamicCall("PushGridcoinDiagnosticData(Qstring)",qsData).toInt(); - #endif - return result; + if (!bGlobalcomInitialized) return 0; + int result = 0; + #if defined(WIN32) && defined(QT_GUI) + QString qsData = ToQstring(data); + result = globalcom->dynamicCall("PushGridcoinDiagnosticData(Qstring)",qsData).toInt(); + #endif + return result; } //R Halford - 6/19/2015 - Let's clean up the windows side by removing all these functions and making a generic interface for comm between Windows and Linux; Start with one new generic function here: double qtExecuteGenericFunction(std::string function, std::string data) { - if (!bGlobalcomInitialized) return 0; + if (!bGlobalcomInitialized) return 0; - int result = 0; - #if defined(WIN32) && defined(QT_GUI) - QString qsData = ToQstring(data); - QString qsFunction = ToQstring(function +"(Qstring)"); - std::string sFunction = function+"(Qstring)"; - if (data=="") - { - sFunction = function + "()"; - globalcom->dynamicCall(sFunction.c_str()); - } - else - { - result = globalcom->dynamicCall(sFunction.c_str(),qsData).toInt(); - } - #endif - return result; + int result = 0; + #if defined(WIN32) && defined(QT_GUI) + QString qsData = ToQstring(data); + QString qsFunction = ToQstring(function +"(Qstring)"); + std::string sFunction = function+"(Qstring)"; + if (data=="") + { + sFunction = function + "()"; + globalcom->dynamicCall(sFunction.c_str()); + } + else + { + result = globalcom->dynamicCall(sFunction.c_str(),qsData).toInt(); + } + #endif + return result; } std::string qtExecuteDotNetStringFunction(std::string function, std::string data) { - std::string sReturnData = ""; - if (!bGlobalcomInitialized) return ""; + std::string sReturnData = ""; + if (!bGlobalcomInitialized) return ""; - #if defined(WIN32) && defined(QT_GUI) - if (!bGlobalcomInitialized) return "?"; - QString qsData = ToQstring(data); - QString qsFunction = ToQstring(function +"(Qstring)"); - std::string sFunction = function+"(Qstring)"; - QString qsReturnData = globalcom->dynamicCall(sFunction.c_str(),qsData).toString(); - sReturnData = FromQString(qsReturnData); - return sReturnData; - #endif - return sReturnData; + #if defined(WIN32) && defined(QT_GUI) + if (!bGlobalcomInitialized) return "?"; + QString qsData = ToQstring(data); + QString qsFunction = ToQstring(function +"(Qstring)"); + std::string sFunction = function+"(Qstring)"; + QString qsReturnData = globalcom->dynamicCall(sFunction.c_str(),qsData).toString(); + sReturnData = FromQString(qsReturnData); + return sReturnData; + #endif + return sReturnData; } @@ -456,23 +388,23 @@ std::string qtExecuteDotNetStringFunction(std::string function, std::string data void qtSyncWithDPORNodes(std::string data) { - #if defined(WIN32) && defined(QT_GUI) - if (!bGlobalcomInitialized) return; - int result = 0; - QString qsData = ToQstring(data); - if (fDebug3) printf("FullSyncWDporNodes"); - std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; - double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); - result = globalcom->dynamicCall("SyncCPIDsWithDPORNodes(Qstring)",qsData).toInt(); - printf("Done syncing. %f %f\r\n",function_call,(double)result); - #endif + #if defined(WIN32) && defined(QT_GUI) + if (!bGlobalcomInitialized) return; + int result = 0; + QString qsData = ToQstring(data); + if (fDebug3) printf("FullSyncWDporNodes"); + std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; + double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + result = globalcom->dynamicCall("SyncCPIDsWithDPORNodes(Qstring)",qsData).toInt(); + printf("Done syncing. %f %f\r\n",function_call,(double)result); + #endif } std::string FromQString(QString qs) { - std::string sOut = qs.toUtf8().constData(); - return sOut; + std::string sOut = qs.toUtf8().constData(); + return sOut; } @@ -480,23 +412,23 @@ std::string FromQString(QString qs) std::string qtGetNeuralContract(std::string data) { - #if defined(WIN32) && defined(QT_GUI) - try - { - if (!bGlobalcomInitialized) return "NA"; - QString qsData = ToQstring(data); - //if (fDebug3) printf("GNC# "); - QString sResult = globalcom->dynamicCall("GetNeuralContract()").toString(); - std::string result = FromQString(sResult); - return result; - } - catch(...) - { - return "?"; - } - #else - return "?"; - #endif + #if defined(WIN32) && defined(QT_GUI) + try + { + if (!bGlobalcomInitialized) return "NA"; + QString qsData = ToQstring(data); + //if (fDebug3) printf("GNC# "); + QString sResult = globalcom->dynamicCall("GetNeuralContract()").toString(); + std::string result = FromQString(sResult); + return result; + } + catch(...) + { + return "?"; + } + #else + return "?"; + #endif } @@ -504,130 +436,92 @@ std::string qtGetNeuralContract(std::string data) std::string qtGetNeuralHash(std::string data) { - #if defined(WIN32) && defined(QT_GUI) - try - { - if (!bGlobalcomInitialized) return "NA"; + #if defined(WIN32) && defined(QT_GUI) + try + { + if (!bGlobalcomInitialized) return "NA"; - QString qsData = ToQstring(data); - QString sResult = globalcom->dynamicCall("GetNeuralHash()").toString(); - std::string result = FromQString(sResult); - return result; - } - catch(...) - { - return "?"; - } - #else - return "?"; - #endif + QString qsData = ToQstring(data); + QString sResult = globalcom->dynamicCall("GetNeuralHash()").toString(); + std::string result = FromQString(sResult); + return result; + } + catch(...) + { + return "?"; + } + #else + return "?"; + #endif } void qtSetSessionInfo(std::string defaultgrcaddress, std::string cpid, double magnitude) { - if (!bGlobalcomInitialized) return; + if (!bGlobalcomInitialized) return; - #if defined(WIN32) && defined(QT_GUI) - int result = 0; - std::string session = defaultgrcaddress + "<COL>" + cpid + "<COL>" + RoundToString(magnitude,1); - QString qsSession = ToQstring(session); - result = globalcom->dynamicCall("SetSessionInfo(Qstring)",qsSession).toInt(); - printf("rs%f",(double)result); - #endif + #if defined(WIN32) && defined(QT_GUI) + int result = 0; + std::string session = defaultgrcaddress + "<COL>" + cpid + "<COL>" + RoundToString(magnitude,1); + QString qsSession = ToQstring(session); + result = globalcom->dynamicCall("SetSessionInfo(Qstring)",qsSession).toInt(); + printf("rs%f",(double)result); + #endif } -int RebootClient() -{ - printf("Executing reboot\r\n"); - if (!bGlobalcomInitialized) return 0; - - QString sFilename = "GRCRestarter.exe"; - QString sArgument = "reboot"; - QString path = QCoreApplication::applicationDirPath() + "\\" + sFilename; - QProcess p; - if (!fTestNet) - { -#ifdef WIN32 - globalcom->dynamicCall("RebootClient()"); -#endif - } - else - { -#ifdef WIN32 - globalcom->dynamicCall("RebootClient()"); -#endif - } - - StartShutdown(); - return 1; -} - - - - void CheckForUpgrade() { - if (!bGlobalcomInitialized) return; + if (!bGlobalcomInitialized) return; - if (bCheckedForUpgrade == false && !fTestNet && bProjectsInitialized) - { - int nNeedsUpgrade = 0; - bCheckedForUpgrade = true; - #ifdef WIN32 - nNeedsUpgrade = globalcom->dynamicCall("ClientNeedsUpgrade()").toInt(); - #endif - printf("Needs upgraded %f\r\n",(double)nNeedsUpgrade); - if (nNeedsUpgrade) UpgradeClient(); - } + if (bCheckedForUpgrade == false && !fTestNet && bProjectsInitialized) + { + int nNeedsUpgrade = 0; + bCheckedForUpgrade = true; + #ifdef WIN32 + nNeedsUpgrade = globalcom->dynamicCall("ClientNeedsUpgrade()").toInt(); + #endif + printf("Needs upgraded %f\r\n",(double)nNeedsUpgrade); + if (nNeedsUpgrade) UpgradeClient(); + } } int64_t IsNeural() { - if (!bGlobalcomInitialized) return 0; - try - { - //NeuralNetwork - int nNeural = 0; - #ifdef WIN32 - nNeural = globalcom->dynamicCall("NeuralNetwork()").toInt(); - #endif - return (int64_t)nNeural; - } - catch(...) - { - printf("Exception %f \r\n",(double)1); - return 0; - } + if (!bGlobalcomInitialized) return 0; + try + { + //NeuralNetwork + int nNeural = 0; +#ifdef WIN32 + nNeural = globalcom->dynamicCall("NeuralNetwork()").toInt(); +#endif + return nNeural; + } + catch(...) + { + printf("Exception\r\n"); + return 0; + } } int UpgradeClient() { - printf("Executing upgrade"); - if (!bGlobalcomInitialized) return 0; + if (!bGlobalcomInitialized) + return 0; + + printf("Executing upgrade"); - QString sFilename = "GRCRestarter.exe"; - QString sArgument = "upgrade"; - QString path = QCoreApplication::applicationDirPath() + "\\" + sFilename; - QProcess p; - if (!fTestNet) - { -#ifdef WIN32 - globalcom->dynamicCall("UpgradeWallet()"); -#endif - } - else - { #ifdef WIN32 - globalcom->dynamicCall("UpgradeWalletTestnet()"); + globalcom->dynamicCall(fTestNet + ? "UpgradeWallet()" + : "UpgradeWalletTestnet()"); #endif - } - StartShutdown(); - return 1; + StartShutdown(); + return 1; } @@ -680,21 +574,21 @@ void BitcoinGUI::createActions() votingAction->setCheckable(true); votingAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_6)); - bxAction = new QAction(QIcon(":/icons/block"), tr("&Block Explorer"), this); - bxAction->setStatusTip(tr("Block Explorer")); - bxAction->setMenuRole(QAction::TextHeuristicRole); + bxAction = new QAction(QIcon(":/icons/block"), tr("&Block Explorer"), this); + bxAction->setStatusTip(tr("Block Explorer")); + bxAction->setMenuRole(QAction::TextHeuristicRole); - exchangeAction = new QAction(QIcon(":/icons/ex"), tr("&Exchange"), this); - exchangeAction->setStatusTip(tr("Web Site")); - exchangeAction->setMenuRole(QAction::TextHeuristicRole); + exchangeAction = new QAction(QIcon(":/icons/ex"), tr("&Exchange"), this); + exchangeAction->setStatusTip(tr("Web Site")); + exchangeAction->setMenuRole(QAction::TextHeuristicRole); - websiteAction = new QAction(QIcon(":/icons/www"), tr("&Web Site"), this); - websiteAction->setStatusTip(tr("Web Site")); - websiteAction->setMenuRole(QAction::TextHeuristicRole); + websiteAction = new QAction(QIcon(":/icons/www"), tr("&Web Site"), this); + websiteAction->setStatusTip(tr("Web Site")); + websiteAction->setMenuRole(QAction::TextHeuristicRole); - chatAction = new QAction(QIcon(":/icons/chat"), tr("&GRC Chat Room"), this); - chatAction->setStatusTip(tr("GRC Chatroom")); - chatAction->setMenuRole(QAction::TextHeuristicRole); + chatAction = new QAction(QIcon(":/icons/chat"), tr("&GRC Chat Room"), this); + chatAction->setStatusTip(tr("GRC Chatroom")); + chatAction->setMenuRole(QAction::TextHeuristicRole); boincAction = new QAction(QIcon(":/images/boinc"), tr("&BOINC"), this); boincAction->setStatusTip(tr("Gridcoin rewards distributed computing with BOINC")); @@ -712,11 +606,11 @@ void BitcoinGUI::createActions() connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage())); connect(votingAction, SIGNAL(triggered()), this, SLOT(votingClicked())); - connect(websiteAction, SIGNAL(triggered()), this, SLOT(websiteClicked())); - connect(bxAction, SIGNAL(triggered()), this, SLOT(bxClicked())); - connect(exchangeAction, SIGNAL(triggered()), this, SLOT(exchangeClicked())); - connect(boincAction, SIGNAL(triggered()), this, SLOT(boincClicked())); - connect(chatAction, SIGNAL(triggered()), this, SLOT(chatClicked())); + connect(websiteAction, SIGNAL(triggered()), this, SLOT(websiteClicked())); + connect(bxAction, SIGNAL(triggered()), this, SLOT(bxClicked())); + connect(exchangeAction, SIGNAL(triggered()), this, SLOT(exchangeClicked())); + connect(boincAction, SIGNAL(triggered()), this, SLOT(boincClicked())); + connect(chatAction, SIGNAL(triggered()), this, SLOT(chatClicked())); quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this); quitAction->setToolTip(tr("Quit application")); @@ -725,46 +619,46 @@ void BitcoinGUI::createActions() - rebuildAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Rebuild Block Chain"), this); - rebuildAction->setStatusTip(tr("Rebuild Block Chain")); - rebuildAction->setMenuRole(QAction::TextHeuristicRole); + rebuildAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Rebuild Block Chain"), this); + rebuildAction->setStatusTip(tr("Rebuild Block Chain")); + rebuildAction->setMenuRole(QAction::TextHeuristicRole); - downloadAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Download Blocks"), this); - downloadAction->setStatusTip(tr("Download Blocks")); - downloadAction->setMenuRole(QAction::TextHeuristicRole); + downloadAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Download Blocks"), this); + downloadAction->setStatusTip(tr("Download Blocks")); + downloadAction->setMenuRole(QAction::TextHeuristicRole); - upgradeAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Upgrade Client"), this); - upgradeAction->setStatusTip(tr("Upgrade Client")); - upgradeAction->setMenuRole(QAction::TextHeuristicRole); + upgradeAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Upgrade Client"), this); + upgradeAction->setStatusTip(tr("Upgrade Client")); + upgradeAction->setMenuRole(QAction::TextHeuristicRole); aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About Gridcoin"), this); aboutAction->setToolTip(tr("Show information about Gridcoin")); aboutAction->setMenuRole(QAction::AboutRole); - miningAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Neural Network"), this); - miningAction->setStatusTip(tr("Neural Network")); - miningAction->setMenuRole(QAction::TextHeuristicRole); + miningAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Neural Network"), this); + miningAction->setStatusTip(tr("Neural Network")); + miningAction->setMenuRole(QAction::TextHeuristicRole); - configAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Advanced Configuration"), this); - configAction->setStatusTip(tr("Advanced Configuration")); - configAction->setMenuRole(QAction::TextHeuristicRole); + configAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Advanced Configuration"), this); + configAction->setStatusTip(tr("Advanced Configuration")); + configAction->setMenuRole(QAction::TextHeuristicRole); - newUserWizardAction = new QAction(QIcon(":/icons/bitcoin"), tr("&New User Wizard"), this); - newUserWizardAction->setStatusTip(tr("New User Wizard")); - newUserWizardAction->setMenuRole(QAction::TextHeuristicRole); - - foundationAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Foundation"), this); - foundationAction->setStatusTip(tr("Foundation")); - foundationAction->setMenuRole(QAction::TextHeuristicRole); + newUserWizardAction = new QAction(QIcon(":/icons/bitcoin"), tr("&New User Wizard"), this); + newUserWizardAction->setStatusTip(tr("New User Wizard")); + newUserWizardAction->setMenuRole(QAction::TextHeuristicRole); - diagnosticsAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Diagnostics"), this); - diagnosticsAction->setStatusTip(tr("Diagnostics")); - diagnosticsAction->setMenuRole(QAction::TextHeuristicRole); + foundationAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Foundation"), this); + foundationAction->setStatusTip(tr("Foundation")); + foundationAction->setMenuRole(QAction::TextHeuristicRole); + diagnosticsAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Diagnostics"), this); + diagnosticsAction->setStatusTip(tr("Diagnostics")); + diagnosticsAction->setMenuRole(QAction::TextHeuristicRole); - faqAction = new QAction(QIcon(":/icons/bitcoin"), tr("FA&Q"), this); - faqAction->setStatusTip(tr("Interactive FAQ")); - faqAction->setMenuRole(QAction::TextHeuristicRole); + + faqAction = new QAction(QIcon(":/icons/bitcoin"), tr("FA&Q"), this); + faqAction->setStatusTip(tr("Interactive FAQ")); + faqAction->setMenuRole(QAction::TextHeuristicRole); optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); optionsAction->setToolTip(tr("Modify configuration options for Gridcoin")); @@ -800,19 +694,19 @@ void BitcoinGUI::createActions() connect(lockWalletAction, SIGNAL(triggered()), this, SLOT(lockWallet())); connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); - connect(rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildClicked())); - connect(upgradeAction, SIGNAL(triggered()), this, SLOT(upgradeClicked())); - connect(downloadAction, SIGNAL(triggered()), this, SLOT(downloadClicked())); - connect(configAction, SIGNAL(triggered()), this, SLOT(configClicked())); + connect(rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildClicked())); + connect(upgradeAction, SIGNAL(triggered()), this, SLOT(upgradeClicked())); + connect(downloadAction, SIGNAL(triggered()), this, SLOT(downloadClicked())); + connect(configAction, SIGNAL(triggered()), this, SLOT(configClicked())); + + connect(miningAction, SIGNAL(triggered()), this, SLOT(miningClicked())); - connect(miningAction, SIGNAL(triggered()), this, SLOT(miningClicked())); + connect(diagnosticsAction, SIGNAL(triggered()), this, SLOT(diagnosticsClicked())); - connect(diagnosticsAction, SIGNAL(triggered()), this, SLOT(diagnosticsClicked())); + connect(foundationAction, SIGNAL(triggered()), this, SLOT(foundationClicked())); + connect(faqAction, SIGNAL(triggered()), this, SLOT(faqClicked())); - connect(foundationAction, SIGNAL(triggered()), this, SLOT(foundationClicked())); - connect(faqAction, SIGNAL(triggered()), this, SLOT(faqClicked())); - - connect(newUserWizardAction, SIGNAL(triggered()), this, SLOT(newUserWizardClicked())); + connect(newUserWizardAction, SIGNAL(triggered()), this, SLOT(newUserWizardClicked())); } void BitcoinGUI::createMenuBar() @@ -837,8 +731,8 @@ void BitcoinGUI::createMenuBar() QMenu *settings = appMenuBar->addMenu(tr("&Settings")); settings->addAction(encryptWalletAction); settings->addAction(changePassphraseAction); - - settings->addAction(unlockWalletAction); + + settings->addAction(unlockWalletAction); settings->addAction(lockWalletAction); settings->addSeparator(); settings->addAction(optionsAction); @@ -851,14 +745,14 @@ void BitcoinGUI::createMenuBar() community->addSeparator(); community->addAction(websiteAction); - QMenu *qmAdvanced = appMenuBar->addMenu(tr("&Advanced")); -#ifdef WIN32 // Some actions in this menu are implemented in Visual Basic and thus only work on Windows - qmAdvanced->addAction(configAction); - qmAdvanced->addAction(miningAction); + QMenu *qmAdvanced = appMenuBar->addMenu(tr("&Advanced")); +#ifdef WIN32 // Some actions in this menu are implemented in Visual Basic and thus only work on Windows + qmAdvanced->addAction(configAction); + qmAdvanced->addAction(miningAction); // qmAdvanced->addAction(newUserWizardAction); - qmAdvanced->addSeparator(); - qmAdvanced->addAction(faqAction); - qmAdvanced->addAction(foundationAction); + qmAdvanced->addSeparator(); + qmAdvanced->addAction(faqAction); + qmAdvanced->addAction(foundationAction); // qmAdvanced->addAction(diagnosticsAction); #endif /* defined(WIN32) */ @@ -872,7 +766,7 @@ void BitcoinGUI::createMenuBar() help->addAction(aboutAction); #ifdef WIN32 help->addSeparator(); - help->addAction(upgradeAction); + help->addAction(upgradeAction); #endif } @@ -894,18 +788,18 @@ void BitcoinGUI::createToolBars() toolbar->addAction(addressBookAction); toolbar->addAction(votingAction); - // Prevent Lock from falling off the page + // Prevent Lock from falling off the page QWidget* spacer = new QWidget(); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); toolbar->addWidget(spacer); spacer->setObjectName("spacer"); - // Unlock Wallet - toolbar->addAction(unlockWalletAction); - toolbar->addAction(lockWalletAction); + // Unlock Wallet + toolbar->addAction(unlockWalletAction); + toolbar->addAction(lockWalletAction); QWidget* webSpacer = new QWidget(); - webSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + webSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); webSpacer->setMaximumHeight(10); toolbar->addWidget(webSpacer); webSpacer->setObjectName("WebSpacer"); @@ -1267,10 +1161,10 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) void BitcoinGUI::askQuestion(std::string caption, std::string body, bool *result) { - QString qsCaption = tr(caption.c_str()); - QString qsBody = tr(body.c_str()); - QMessageBox::StandardButton retval = QMessageBox::question(this, qsCaption, qsBody, QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Cancel); - *result = (retval == QMessageBox::Yes); + QString qsCaption = tr(caption.c_str()); + QString qsBody = tr(body.c_str()); + QMessageBox::StandardButton retval = QMessageBox::question(this, qsCaption, qsBody, QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Cancel); + *result = (retval == QMessageBox::Yes); } @@ -1290,8 +1184,8 @@ void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee) std::string tostdstring(QString q) { - std::string ss1 = q.toLocal8Bit().constData(); - return ss1; + std::string ss1 = q.toLocal8Bit().constData(); + return ss1; } @@ -1299,96 +1193,94 @@ std::string tostdstring(QString q) bool CreateNewConfigFile(std::string boinc_email) { - std::string filename = "gridcoinresearch.conf"; - boost::filesystem::path path = GetDataDir() / filename; - std::ofstream myConfig; - myConfig.open (path.string().c_str()); - std::string row = "cpumining=true\r\n"; - myConfig << row; - row = "email=" + boinc_email + "\r\n"; - myConfig << row; - row = "addnode=node.gridcoin.us \r\n"; - myConfig << row; - row = "addnode=gridcoin.asia \r\n"; - myConfig << row; - row = "addnode=grcmagnitude.com \r\n"; - myConfig << row; - myConfig.close(); - return true; + std::string filename = "gridcoinresearch.conf"; + boost::filesystem::path path = GetDataDir() / filename; + std::ofstream myConfig; + myConfig.open (path.string().c_str()); + std::string row = "email=" + boinc_email + "\r\n"; + myConfig << row; + row = "addnode=node.gridcoin.us \r\n"; + myConfig << row; + row = "addnode=gridcoin.asia \r\n"; + myConfig << row; + row = "addnode=grcmagnitude.com \r\n"; + myConfig << row; + myConfig.close(); + return true; } bool ForceInAddNode(std::string sMyAddNode) { - LOCK(cs_vAddedNodes); - std::vector<std::string>::iterator it = vAddedNodes.begin(); - for(; it != vAddedNodes.end(); it++) - if (sMyAddNode == *it) + LOCK(cs_vAddedNodes); + std::vector<std::string>::iterator it = vAddedNodes.begin(); + for(; it != vAddedNodes.end(); it++) + if (sMyAddNode == *it) break; if (it != vAddedNodes.end()) return false; - vAddedNodes.push_back(sMyAddNode); - return true; + vAddedNodes.push_back(sMyAddNode); + return true; } void BitcoinGUI::NewUserWizard() { - if (!IsConfigFileEmpty()) return; - QString boincemail = ""; - //Typhoon- Check to see if boinc exists in default path - 11-19-2014 - - std::string sourcefile = GetBoincDataDir() + "client_state.xml"; - std::string sout = ""; - sout = getfilecontents(sourcefile); - //bool BoincInstalled = true; - std::string sBoincNarr = ""; - if (sout == "-1") - { - printf("Boinc not installed in default location! \r\n"); - //BoincInstalled=false; - std::string nicePath = GetBoincDataDir(); - sBoincNarr = "Boinc is not installed in default location " + nicePath + "! Please set boincdatadir=c:\\programdata\\boinc\\ to the correct path where Boincs programdata directory resides."; - } - - bool ok; - boincemail = QInputDialog::getText(this, tr("New User Wizard"), + if (!IsConfigFileEmpty()) return; + QString boincemail = ""; + //Typhoon- Check to see if boinc exists in default path - 11-19-2014 + + std::string sourcefile = GetBoincDataDir() + "client_state.xml"; + std::string sout = ""; + sout = getfilecontents(sourcefile); + //bool BoincInstalled = true; + std::string sBoincNarr = ""; + if (sout == "-1") + { + printf("Boinc not installed in default location! \r\n"); + //BoincInstalled=false; + std::string nicePath = GetBoincDataDir(); + sBoincNarr = "Boinc is not installed in default location " + nicePath + "! Please set boincdatadir=c:\\programdata\\boinc\\ to the correct path where Boincs programdata directory resides."; + } + + bool ok; + boincemail = QInputDialog::getText(this, tr("New User Wizard"), tr("Please enter your boinc E-mail address, or click <Cancel> to skip for now:"), - QLineEdit::Normal, + QLineEdit::Normal, "", &ok); - if (ok && !boincemail.isEmpty()) - { - std::string new_email = tostdstring(boincemail); - boost::to_lower(new_email); - printf("User entered %s \r\n",new_email.c_str()); - //Create Config File - CreateNewConfigFile(new_email); - QString strMessage = tr("Created new Configuration File Successfully. "); - QMessageBox::warning(this, tr("New Account Created - Welcome Aboard!"), strMessage); - //Load CPIDs: - HarvestCPIDs(true); - } - else - { - //Create Config File - CreateNewConfigFile("investor"); - QString strMessage = tr("To get started with Boinc, run the boinc client, choose projects, then populate the gridcoinresearch.conf file in %appdata%\\GridcoinResearch with your boinc e-mail address. To run this wizard again, please delete the gridcoinresearch.conf file. "); - QMessageBox::warning(this, tr("New User Wizard - Skipped"), strMessage); - } - // Read in the mapargs, and set the seed nodes 10-13-2015 + if (ok && !boincemail.isEmpty()) + { + std::string new_email = tostdstring(boincemail); + boost::to_lower(new_email); + printf("User entered %s \r\n",new_email.c_str()); + //Create Config File + CreateNewConfigFile(new_email); + QString strMessage = tr("Created new Configuration File Successfully. "); + QMessageBox::warning(this, tr("New Account Created - Welcome Aboard!"), strMessage); + //Load CPIDs: + HarvestCPIDs(true); + } + else + { + //Create Config File + CreateNewConfigFile("investor"); + QString strMessage = tr("To get started with Boinc, run the boinc client, choose projects, then populate the gridcoinresearch.conf file in %appdata%\\GridcoinResearch with your boinc e-mail address. To run this wizard again, please delete the gridcoinresearch.conf file. "); + QMessageBox::warning(this, tr("New User Wizard - Skipped"), strMessage); + } + // Read in the mapargs, and set the seed nodes 10-13-2015 ReadConfigFile(mapArgs, mapMultiArgs); - //Force some addnodes in to get user started - ForceInAddNode("node.gridcoin.us"); - ForceInAddNode("gridcoin.asia"); - ForceInAddNode("grcmagnitude.com"); - ForceInAddNode("amsterdam.grcnode.co.uk"); - ForceInAddNode("london.grcnode.co.uk"); - ForceInAddNode("frankfurt.grcnode.co.uk"); - ForceInAddNode("nyc.grcnode.co.uk"); - - if (sBoincNarr != "") - { - QString qsMessage = tr(sBoincNarr.c_str()); - QMessageBox::warning(this, tr("Attention! - Boinc Path Error!"), qsMessage); - } + //Force some addnodes in to get user started + ForceInAddNode("node.gridcoin.us"); + ForceInAddNode("gridcoin.asia"); + ForceInAddNode("grcmagnitude.com"); + ForceInAddNode("amsterdam.grcnode.co.uk"); + ForceInAddNode("london.grcnode.co.uk"); + ForceInAddNode("frankfurt.grcnode.co.uk"); + ForceInAddNode("nyc.grcnode.co.uk"); + + if (sBoincNarr != "") + { + QString qsMessage = tr(sBoincNarr.c_str()); + QMessageBox::warning(this, tr("Attention! - Boinc Path Error!"), qsMessage); + } } @@ -1432,37 +1324,37 @@ void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int void BitcoinGUI::rebuildClicked() { - printf("Rebuilding..."); + printf("Rebuilding..."); ReindexWallet(); } void BitcoinGUI::upgradeClicked() { - printf("Upgrading Gridcoin..."); - UpgradeClient(); + printf("Upgrading Gridcoin..."); + UpgradeClient(); } void BitcoinGUI::downloadClicked() { - DownloadBlocks(); + DownloadBlocks(); } void BitcoinGUI::configClicked() { #ifdef WIN32 - if (!bGlobalcomInitialized) return; - std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; - qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); - globalcom->dynamicCall("ShowConfig()"); + if (!bGlobalcomInitialized) return; + std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; + qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + globalcom->dynamicCall("ShowConfig()"); #endif } void BitcoinGUI::diagnosticsClicked() { #ifdef WIN32 - if (!bGlobalcomInitialized) return; - qtSetSessionInfo(DefaultWalletAddress(), GlobalCPUMiningCPID.cpid, GlobalCPUMiningCPID.Magnitude); - bool result = PushGridcoinDiagnostics(); + if (!bGlobalcomInitialized) return; + qtSetSessionInfo(DefaultWalletAddress(), GlobalCPUMiningCPID.cpid, GlobalCPUMiningCPID.Magnitude); + bool result = PushGridcoinDiagnostics(); globalcom->dynamicCall("ShowDiagnostics()"); #endif } @@ -1470,13 +1362,13 @@ void BitcoinGUI::diagnosticsClicked() void BitcoinGUI::foundationClicked() { #ifdef WIN32 - if (!bGlobalcomInitialized) return; - std::string sVotingPayload = ""; - GetJSONPollsReport(true,"",sVotingPayload,true); - qtExecuteGenericFunction("SetGenericVotingData",sVotingPayload); - std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; - qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); - qtSetSessionInfo(DefaultWalletAddress(), GlobalCPUMiningCPID.cpid, GlobalCPUMiningCPID.Magnitude); + if (!bGlobalcomInitialized) return; + std::string sVotingPayload = ""; + GetJSONPollsReport(true,"",sVotingPayload,true); + qtExecuteGenericFunction("SetGenericVotingData",sVotingPayload); + std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; + qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + qtSetSessionInfo(DefaultWalletAddress(), GlobalCPUMiningCPID.cpid, GlobalCPUMiningCPID.Magnitude); globalcom->dynamicCall("ShowFoundation()"); #endif } @@ -1485,10 +1377,10 @@ void BitcoinGUI::foundationClicked() void BitcoinGUI::faqClicked() { #ifdef WIN32 - if (!bGlobalcomInitialized) return; - std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; - double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); - globalcom->dynamicCall("ShowFAQ()"); + if (!bGlobalcomInitialized) return; + std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; + double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + globalcom->dynamicCall("ShowFAQ()"); #endif } @@ -1496,7 +1388,7 @@ void BitcoinGUI::faqClicked() void BitcoinGUI::newUserWizardClicked() { #ifdef WIN32 - if (!bGlobalcomInitialized) return; + if (!bGlobalcomInitialized) return; globalcom->dynamicCall("ShowNewUserWizard()"); #endif } @@ -1505,10 +1397,10 @@ void BitcoinGUI::miningClicked() { #ifdef WIN32 - if (!bGlobalcomInitialized) return; - std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; - double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); - globalcom->dynamicCall("ShowMiningConsole()"); + if (!bGlobalcomInitialized) return; + std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; + double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + globalcom->dynamicCall("ShowMiningConsole()"); #endif } @@ -1774,13 +1666,13 @@ void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden) bool Timer(std::string timer_name, int max_ms) { - mvTimers[timer_name] = mvTimers[timer_name] + 1; - if (mvTimers[timer_name] > max_ms) - { - mvTimers[timer_name]=0; - return true; - } - return false; + mvTimers[timer_name] = mvTimers[timer_name] + 1; + if (mvTimers[timer_name] > max_ms) + { + mvTimers[timer_name]=0; + return true; + } + return false; } @@ -1808,14 +1700,14 @@ void BitcoinGUI::updateWeight() std::string getMacAddress() { - std::string myMac = "?:?:?:?"; + std::string myMac = "?:?:?:?"; foreach(QNetworkInterface netInterface, QNetworkInterface::allInterfaces()) { // Return only the first non-loopback MAC Address if (!(netInterface.flags() & QNetworkInterface::IsLoopBack)) - { + { myMac = netInterface.hardwareAddress().toUtf8().constData(); - } + } } return myMac; } @@ -1824,83 +1716,36 @@ std::string getMacAddress() void ReinstantiateGlobalcom() { #ifdef WIN32 + if (bGlobalcomInitialized) + return; - if (bGlobalcomInitialized) return; - - //Note, on Windows, if the performance counters are corrupted, rebuild them by going to an elevated command prompt and - //issue the command: lodctr /r (to rebuild the performance counters in the registry) - std::string os = GetArg("-os", "windows"); - if (os == "linux" || os == "mac") - { - printf("Instantiating globalcom for Linux"); - globalcom = new QAxObject("Boinc.LinuxUtilization"); - } - else - { - printf("Instantiating globalcom for Windows %f",(double)0); - try - { - globalcom = new QAxObject("BoincStake.Utilization"); - } - catch(...) - { - printf("Failed to instantiate globalcom."); - } - printf("Instantiated globalcom for Windows %f",(double)1); - - } - bGlobalcomInitialized = true; -#endif -} - - - -void ExecuteCode() -{ - if (!bGlobalcomInitialized) return; - std::string q = "\""; - std::string sCode = "For x = 1 to 5:sOut=sOut + " + q + "COUNTING: " + q + "+ trim(x):Next x:MsgBox(" + q + "Hello: " - + q + " + sOut,MsgBoxStyle.Critical," + q + "Message Title" + q + ")"; - - QString qsCode = QString::fromUtf8(sCode.c_str()); - #ifdef WIN32 - globalcom->dynamicCall("ExecuteCode(Qstring)", qsCode); - #endif - -} - + // Note, on Windows, if the performance counters are corrupted, rebuild them + // by going to an elevated command prompt and issue the command: lodctr /r + // (to rebuild the performance counters in the registry) + printf("Instantiating globalcom for Windows %f",(double)0); + try + { + globalcom = new QAxObject("BoincStake.Utilization"); + printf("Instantiated globalcom for Windows"); + } + catch(...) + { + printf("Failed to instantiate globalcom."); + } -std::string SQLQuery() -{ - /* - QSqlDatabase db = QSqlDatabase::addDatabase("QPGridcoin"); - db.setHostName("arachnid1"); - db.setDatabaseName("dbname"); - db.setUserName("thelogin"); - db.setPassword("thepass"); - bool ok = db.open(); - if(ok) - { - QSqlQuery query("SELECT country FROM confirm"); - while (query.next()) - { - QString country = query.value(0).toString(); - } - } - return ""; - */ - return ""; + bGlobalcomInitialized = true; +#endif } void BitcoinGUI::timerfire() { - try - { + try + { if ( (nRegVersion==0 || Timer("start",10)) && !bGlobalcomInitialized) - { + { ReinstantiateGlobalcom(); nRegVersion=9999; - + static bool bNewUserWizardNotified = false; if (!bNewUserWizardNotified) { @@ -1909,106 +1754,96 @@ void BitcoinGUI::timerfire() } #ifdef WIN32 if (!bGlobalcomInitialized) return; - + nRegVersion = globalcom->dynamicCall("Version()").toInt(); sRegVer = boost::lexical_cast<std::string>(nRegVersion); #endif } - if (bGlobalcomInitialized) - { - //R Halford - Allow .NET to talk to Core: 6-21-2015 - #ifdef WIN32 - std::string sData = qtExecuteDotNetStringFunction("GetDotNetMessages",""); - if (!sData.empty()) - { - std::string RPCCommand = ExtractXML(sData,"<COMMAND>","</COMMAND>"); - std::string Argument1 = ExtractXML(sData,"<ARG1>","</ARG1>"); - std::string Argument2 = ExtractXML(sData,"<ARG2>","</ARG2>"); - - if (RPCCommand=="vote") - { - std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; - double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); - std::string response = ExecuteRPCCommand("vote",Argument1,Argument2); - double resultcode = qtExecuteGenericFunction("SetRPCResponse"," "+response); - } - else if (RPCCommand=="rain") - { - std::string response = ExecuteRPCCommand("rain",Argument1,Argument2); - double resultcode = qtExecuteGenericFunction("SetRPCResponse"," "+response); - } - else if (RPCCommand=="addpoll") - { - std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; - double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); - std::string Argument3 = ExtractXML(sData,"<ARG3>","</ARG3>"); - std::string Argument4 = ExtractXML(sData,"<ARG4>","</ARG4>"); - std::string Argument5 = ExtractXML(sData,"<ARG5>","</ARG5>"); - std::string Argument6 = ExtractXML(sData,"<ARG6>","</ARG6>"); - std::string response = ExecuteRPCCommand("addpoll",Argument1,Argument2,Argument3,Argument4,Argument5,Argument6); - double resultcode = qtExecuteGenericFunction("SetRPCResponse"," "+response); - } - else if (RPCCommand == "addattachment") - { - msAttachmentGuid = Argument1; - printf("\r\n attachment added %s \r\n",msAttachmentGuid.c_str()); - } - - } - #endif - } - - - if (Timer("status_update",5)) - { - GetGlobalStatus(); - bForceUpdate=true; - } - - if (bForceUpdate) - { - bForceUpdate=false; - overviewPage->updateglobalstatus(); - setNumConnections(clientModel->getNumConnections()); - } + if (bGlobalcomInitialized) + { + //R Halford - Allow .NET to talk to Core: 6-21-2015 + #ifdef WIN32 + std::string sData = qtExecuteDotNetStringFunction("GetDotNetMessages",""); + if (!sData.empty()) + { + std::string RPCCommand = ExtractXML(sData,"<COMMAND>","</COMMAND>"); + std::string Argument1 = ExtractXML(sData,"<ARG1>","</ARG1>"); + std::string Argument2 = ExtractXML(sData,"<ARG2>","</ARG2>"); + + if (RPCCommand=="vote") + { + std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; + double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + std::string response = ExecuteRPCCommand("vote",Argument1,Argument2); + double resultcode = qtExecuteGenericFunction("SetRPCResponse"," "+response); + } + else if (RPCCommand=="rain") + { + std::string response = ExecuteRPCCommand("rain",Argument1,Argument2); + double resultcode = qtExecuteGenericFunction("SetRPCResponse"," "+response); + } + else if (RPCCommand=="addpoll") + { + std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; + double function_call = qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); + std::string Argument3 = ExtractXML(sData,"<ARG3>","</ARG3>"); + std::string Argument4 = ExtractXML(sData,"<ARG4>","</ARG4>"); + std::string Argument5 = ExtractXML(sData,"<ARG5>","</ARG5>"); + std::string Argument6 = ExtractXML(sData,"<ARG6>","</ARG6>"); + std::string response = ExecuteRPCCommand("addpoll",Argument1,Argument2,Argument3,Argument4,Argument5,Argument6); + double resultcode = qtExecuteGenericFunction("SetRPCResponse"," "+response); + } + else if (RPCCommand == "addattachment") + { + msAttachmentGuid = Argument1; + printf("\r\n attachment added %s \r\n",msAttachmentGuid.c_str()); + } + + } + #endif + } - } - catch(std::runtime_error &e) - { - printf("GENERAL RUNTIME ERROR!"); - } + if (Timer("status_update",5)) + { + GetGlobalStatus(); + bForceUpdate=true; + } -} + if (bForceUpdate) + { + bForceUpdate=false; + overviewPage->updateglobalstatus(); + setNumConnections(clientModel->getNumConnections()); + } + } + catch(std::runtime_error &e) + { + printf("GENERAL RUNTIME ERROR!"); + } -QString BitcoinGUI::toqstring(int o) -{ - std::string pre=""; - pre=strprintf("%d",o); - QString str1 = QString::fromUtf8(pre.c_str()); - return str1; } double GetPOREstimatedTime(double RSAWeight) { - if (RSAWeight == 0) return 0; - //RSA Weight ranges from 0 - 5600 - double orf = 5600-RSAWeight; - if (orf < 1) orf = 1; - double eta = orf/5600; - if (eta > 1) orf = 1; - eta = eta * (60*60*24); - return eta; + if (RSAWeight == 0) return 0; + //RSA Weight ranges from 0 - 5600 + double orf = 5600-RSAWeight; + if (orf < 1) orf = 1; + double eta = orf/5600; + if (eta > 1) orf = 1; + eta = eta * (60*60*24); + return eta; } QString BitcoinGUI::GetEstimatedTime(unsigned int nEstimateTime) { - QString text; - if (nEstimateTime < 60) + QString text; + if (nEstimateTime < 60) { text = tr("%n second(s)", "", nEstimateTime); } @@ -2024,21 +1859,20 @@ QString BitcoinGUI::GetEstimatedTime(unsigned int nEstimateTime) { text = tr("%n day(s)", "", nEstimateTime/(60*60*24)); } - return text; + return text; } void BitcoinGUI::updateStakingIcon() { - uint64_t nWeight, nLastInterval; std::string ReasonNotStaking; { LOCK(MinerStatus.lock); // not using real weigh to not break calculation nWeight = MinerStatus.ValueSum; nLastInterval = MinerStatus.nLastCoinStakeSearchInterval; - ReasonNotStaking = MinerStatus.ReasonNotStaking; + ReasonNotStaking = MinerStatus.ReasonNotStaking; } uint64_t nNetworkWeight = GetPoSKernelPS(); @@ -2047,64 +1881,17 @@ void BitcoinGUI::updateStakingIcon() if (staking) { - if (fDebug10) printf("StakeIcon Vitals BH %f, NetWeight %f, Weight %f \r\n", (double)GetTargetSpacing(nBestHeight),(double)nNetworkWeight,(double)nWeight); + if (fDebug10) printf("StakeIcon Vitals BH %f, NetWeight %f, Weight %f \r\n", (double)GetTargetSpacing(nBestHeight),(double)nNetworkWeight,(double)nWeight); QString text = GetEstimatedTime(nEstimateTime); - /* - //Halford - 1-9-2015 - Calculate time for POR Block: - unsigned int nPOREstimate = (unsigned int)GetPOREstimatedTime(GlobalCPUMiningCPID.RSAWeight); - QString PORText = "Estimated time to earn POR Reward: " + GetEstimatedTime(nPOREstimate); - if (nPOREstimate == 0) PORText=""; - */ - labelStakingIcon->setPixmap(QIcon(":/icons/staking_on").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); - + labelStakingIcon->setPixmap(QIcon(":/icons/staking_on").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelStakingIcon->setToolTip(tr("Staking.<br>Your weight is %1<br>Network weight is %2<br><b>Estimated</b> time to earn reward is %3.") - .arg(nWeight).arg(nNetworkWeight).arg(text)); - /* - msMiningErrors5 = "Interest: " + FromQString(text); - if (nPOREstimate > 0 && !(msPrimaryCPID=="INVESTOR" || msMiningCPID.empty())) msMiningErrors6 = "POR: " + FromQString(GetEstimatedTime(nPOREstimate)); - */ + .arg(nWeight).arg(nNetworkWeight).arg(text)); + } else { labelStakingIcon->setPixmap(QIcon(":/icons/staking_off").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); - /* - if (pwalletMain && pwalletMain->IsLocked()) - { - labelStakingIcon->setToolTip(tr("Not staking because wallet is locked")); - //msMiningErrors6="Wallet Locked"; - } - else if (vNodes.empty()) - { - labelStakingIcon->setToolTip(tr("Not staking because wallet is offline")); - } - else if (IsInitialBlockDownload()) - { - labelStakingIcon->setToolTip(tr("Not staking because wallet is syncing")); - msMiningErrors6 = "Syncing"; - } - else if (!nLastCoinStakeSearchInterval && !nWeight) - { - labelStakingIcon->setToolTip(tr("Not staking because you don't have mature coins and stake weight is too low.")); - msMiningErrors6 = "No Mature Coins; Stakeweight too low"; - } - else if (!nWeight) - { - labelStakingIcon->setToolTip(tr("Not staking because you don't have mature coins")); - msMiningErrors6 = "No mature coins"; - } - else if (!nLastCoinStakeSearchInterval) - { - labelStakingIcon->setToolTip(tr("Searching for mature coins... Please wait")); - msMiningErrors6 = "Searching for coins"; - } - else - { - labelStakingIcon->setToolTip(tr("Not staking")); - msMiningErrors6 = "Not staking yet"; - } - */ - - //Part of this string wont be translated :( - labelStakingIcon->setToolTip(tr("Not staking; %1").arg(QString(ReasonNotStaking.c_str()))); + //Part of this string wont be translated :( + labelStakingIcon->setToolTip(tr("Not staking; %1").arg(QString(ReasonNotStaking.c_str()))); } } diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 4b0b7253b2..dda376d4af 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -44,10 +44,6 @@ class BitcoinGUI : public QMainWindow { Q_OBJECT public: - QString toqstring(int o); - - - explicit BitcoinGUI(QWidget *parent = 0); ~BitcoinGUI(); diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index 9d20814f9b..288ebeae6a 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -6,7 +6,6 @@ #include <QMessageBox> #include <QModelIndex> -void ExecuteCode(); QString ToQString(std::string s); std::string qtExecuteDotNetStringFunction(std::string function, std::string data); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 29e0b06da1..2e62bd93b5 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -139,7 +139,6 @@ int64_t GetRSAWeightByCPID(std::string cpid); double GetUntrustedMagnitude(std::string cpid, double& out_owed); extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry); extern enum Checkpoints::CPMode CheckpointsMode; -int RebootClient(); int ReindexWallet(); extern Array MagnitudeReportCSV(bool detail); std::string getfilecontents(std::string filename); @@ -1187,25 +1186,15 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("Restore Point",r)); results.push_back(entry); } - else if (sItem == "reboot") + else if (sItem == "restart") { - int r=1; - #if defined(WIN32) && defined(QT_GUI) - RebootClient(); - #endif - entry.push_back(Pair("RebootClient",r)); - results.push_back(entry); - - } - else if (sItem == "restartclient") - { - printf("Restarting Gridcoin..."); - int iResult = 0; - #if defined(WIN32) && defined(QT_GUI) - iResult = RestartClient(); - #endif - entry.push_back(Pair("Restarting",(double)iResult)); - results.push_back(entry); + printf("Restarting Gridcoin..."); + int iResult = 0; +#if defined(WIN32) && defined(QT_GUI) + iResult = RestartClient(); +#endif + entry.push_back(Pair("result", iResult)); + results.push_back(entry); } else if (sItem == "sendblock") { @@ -2389,15 +2378,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("Download Blocks",r)); results.push_back(entry); } - else if (sItem == "executecode") - { - printf("Executing .net code\r\n"); - #if defined(WIN32) && defined(QT_GUI) - - ExecuteCode(); - #endif - - } else if (sItem == "getnextproject") { GetNextProject(true); @@ -2523,7 +2503,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("execute neuralresponse", "Requests a response from neural network")); entry.push_back(Pair("execute rain <raindata>", "Sends rain to specified users. Format Address<COL>Amount<ROW>...")); #if defined(WIN32) && defined(QT_GUI) - entry.push_back(Pair("execute reboot", "Reboots wallet")); entry.push_back(Pair("execute reindex", "Reindex blockchain")); #endif entry.push_back(Pair("execute resendwallettx", "Resends a wallet tx")); diff --git a/src/wallet.cpp b/src/wallet.cpp index be8e4b0c71..f5f5d11ecd 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -24,7 +24,6 @@ using namespace std; double cdbl(std::string s, int place); std::string SendReward(std::string sAddress, int64_t nAmount); -void qtUpdateConfirm(std::string txid); extern double MintLimiter(double PORDiff,int64_t RSA_WEIGHT,std::string cpid,int64_t locktime); int64_t GetRSAWeightByCPID(std::string cpid); void AddPeek(std::string data); @@ -535,42 +534,6 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent); } - //// debug print 12-9-2014 (received coins) - if (fDebug) printf("AddToWallet %s %s %s \n", wtxIn.GetHash().ToString().c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); - if (fInsertedNew) - { - // If this is a tracked tx, update via SQL: - if (!wtxIn.hashBoinc.empty() && bGlobalcomInitialized) - { - if (Contains(wtxIn.hashBoinc,"<TRACK>")) - { - //wtx.GetHash().ToString() - printf("Updating tx id %s",wtxIn.GetHash().ToString().c_str()); - #if defined(WIN32) && defined(QT_GUI) - qtUpdateConfirm(wtxIn.GetHash().ToString()); - #endif - printf("Updated."); - } - } - - // (Reserved:If this is a coinbase, update the interest and the researchsubsidy on the tx: (12-17-2014 Halford)): - // This dead code is reserved for future use: If we ever add new fields to a wallet TX, it will be useful in remembering how to update the values upon RECEIVING money from an outside source - if (false) - { - CBlockIndex* pboincblockindex = mapBlockIndex[wtxIn.hashBlock]; - CBlock blk; - bool h = blk.ReadFromDisk(pboincblockindex); - if (h) - { - //MiningCPID mcpidWalletTx = DeserializeBoincBlock(blk.vtx[0].hashBoinc); - //wtx.nResearchSubsidy = mcpidWalletTx.ResearchSubsidy; - //wtx.nInterestSubsidy = mcpidWalletTx.InterestSubsidy; - //printf("Logging coinbase tx in Research %f, Interest %f",(double)wtx.nResearchSubsidy,(double)wtx.nInterestSubsidy); - } - } - - - } // Write to disk if (fInsertedNew || fUpdated) if (!wtx.WriteToDisk()) From 7248ab426a519ce89dfe7435d4547db01fd08a0c Mon Sep 17 00:00:00 2001 From: Marco Nilsson <denravonska@gmail.com> Date: Thu, 5 Oct 2017 10:59:37 +0200 Subject: [PATCH 018/166] Optimize split operation. (#672) Avoid modifying the incoming string. This makes the operation 12% faster on short strings and 48% faster on long strings like a contract. --- src/beacon.cpp | 1 - src/init.cpp | 1 - src/main.cpp | 21 --------------------- src/qt/votingdialog.cpp | 2 +- src/rpcblockchain.cpp | 1 - src/test/util_tests.cpp | 11 +++++++++++ src/util.cpp | 16 ++++++++++++++++ src/util.h | 1 + 8 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/beacon.cpp b/src/beacon.cpp index 37b7f99d21..e402da81b9 100755 --- a/src/beacon.cpp +++ b/src/beacon.cpp @@ -4,7 +4,6 @@ #include "key.h" #include "main.h" -std::vector<std::string> split(std::string s, std::string delim); extern std::string SignBlockWithCPID(std::string sCPID, std::string sBlockHash); extern bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature); std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxSeconds); diff --git a/src/init.cpp b/src/init.cpp index 65671f2c01..d7cfe069e2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -22,7 +22,6 @@ #include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith() #include "global_objects_noui.hpp" -std::vector<std::string> split(std::string s, std::string delim); bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); extern boost::thread_group threadGroup; diff --git a/src/main.cpp b/src/main.cpp index 60f0cf0982..5526ac6744 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -291,7 +291,6 @@ extern void LoadCPIDsInBackground(); extern void ThreadCPIDs(); extern void GetGlobalStatus(); -extern std::vector<std::string> split(std::string s, std::string delim); extern bool ProjectIsValid(std::string project); double GetNetworkAvgByProject(std::string projectname); @@ -2363,26 +2362,6 @@ const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& in return txPrev.vout[input.prevout.n]; } - -std::vector<std::string> split(std::string s, std::string delim) -{ - //Split a std::string by a std::string delimiter into a vector of strings: - size_t pos = 0; - std::string token; - std::vector<std::string> elems; - while ((pos = s.find(delim)) != std::string::npos) - { - token = s.substr(0, pos); - elems.push_back(token); - s.erase(0, pos + delim.length()); - } - elems.push_back(s); - return elems; - -} - - - int64_t CTransaction::GetValueIn(const MapPrevTx& inputs) const { if (IsCoinBase()) diff --git a/src/qt/votingdialog.cpp b/src/qt/votingdialog.cpp index 0b25fc127a..319c590359 100644 --- a/src/qt/votingdialog.cpp +++ b/src/qt/votingdialog.cpp @@ -32,10 +32,10 @@ #include "json/json_spirit.h" #include "votingdialog.h" +#include "util.h" extern json_spirit::Array GetJSONPollsReport(bool bDetail, std::string QueryByTitle, std::string& out_export, bool bIncludeExpired); -extern std::vector<std::string> split(std::string s, std::string delim); extern std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); extern std::string ExecuteRPCCommand(std::string method, std::string arg1, std::string arg2); extern std::string ExecuteRPCCommand(std::string method, std::string arg1, std::string arg2, std::string arg3, std::string arg4, std::string arg5, std::string arg6); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 2e62bd93b5..fe8e2f8cd3 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -145,7 +145,6 @@ std::string getfilecontents(std::string filename); int CreateRestorePoint(); int DownloadBlocks(); double cdbl(std::string s, int place); -std::vector<std::string> split(std::string s, std::string delim); double LederstrumpfMagnitude2(double mag,int64_t locktime); bool IsCPIDValidv2(MiningCPID& mc, int height); std::string RetrieveMd5(std::string s1); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index f5f55718f6..db6c7bcc54 100755 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -360,4 +360,15 @@ BOOST_AUTO_TEST_CASE(util_VerifyRoundToString) BOOST_CHECK_EQUAL("1.2346", RoundToString(1.23456789, 4)); } +BOOST_AUTO_TEST_CASE(util_VerifySplit) +{ + const std::string str("Hello;;My;;String;;"); + const auto res = split(str, ";;"); + BOOST_CHECK(res.size() == 4); + BOOST_CHECK_EQUAL("Hello", res[0]); + BOOST_CHECK_EQUAL("My", res[1]); + BOOST_CHECK_EQUAL("String", res[2]); + BOOST_CHECK_EQUAL("", res[3]); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/util.cpp b/src/util.cpp index 622a464ba1..1dca750df5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1467,6 +1467,22 @@ bool Contains(const std::string& data, const std::string& instring) return data.find(instring) != std::string::npos; } +std::vector<std::string> split(const std::string& s, const std::string& delim) +{ + size_t pos = 0; + size_t end = 0; + std::vector<std::string> elems; + + while((end = s.find(delim, pos)) != std::string::npos) + { + elems.push_back(s.substr(pos, end - pos)); + pos = end + delim.size(); + } + + // Append final value + elems.push_back(s.substr(pos, end - pos)); +} + std::string GetNeuralVersion() { diff --git a/src/util.h b/src/util.h index 7c90f5d2f3..22ca658f9c 100644 --- a/src/util.h +++ b/src/util.h @@ -227,6 +227,7 @@ std::string ToString(const T& val) } bool Contains(const std::string& data, const std::string& instring); +std::vector<std::string> split(const std::string& s, const std::string& delim); std::string MakeSafeMessage(const std::string& messagestring); From 60e1823ee7eca7cb9a4b20e4c09e47422653c118 Mon Sep 17 00:00:00 2001 From: Paul Jensen <eastendmumbles@gmail.com> Date: Thu, 5 Oct 2017 21:37:01 -0700 Subject: [PATCH 019/166] bug fix for ravons optimization (#676) --- src/util.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util.cpp b/src/util.cpp index 1dca750df5..bf89dd2b61 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1481,6 +1481,7 @@ std::vector<std::string> split(const std::string& s, const std::string& delim) // Append final value elems.push_back(s.substr(pos, end - pos)); + return elems; } std::string GetNeuralVersion() From 7df4d8a38486c42cc66c7b89475fb3add02200af Mon Sep 17 00:00:00 2001 From: Marco Nilsson <denravonska@gmail.com> Date: Fri, 6 Oct 2017 10:11:15 +0200 Subject: [PATCH 020/166] Remove unnecessary Gridcoin Services thread. --- src/global_objects_noui.hpp | 1 - src/main.cpp | 1 - src/net.cpp | 59 +------------------------------------ src/net.h | 3 +- 4 files changed, 2 insertions(+), 62 deletions(-) diff --git a/src/global_objects_noui.hpp b/src/global_objects_noui.hpp index 9a6d2e6fb6..d4d06d6e97 100755 --- a/src/global_objects_noui.hpp +++ b/src/global_objects_noui.hpp @@ -22,7 +22,6 @@ extern bool bAllowBackToBack; extern bool CreatingCPUBlock; extern bool bStakeMinerOutOfSyncWithNetwork; extern bool bDoTally; -extern bool bExecuteGridcoinServices; extern bool bTallyFinished; extern bool bGridcoinGUILoaded; diff --git a/src/main.cpp b/src/main.cpp index 5526ac6744..c90efb2ddd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -278,7 +278,6 @@ bool bCheckedForUpgradeLive = false; bool bGlobalcomInitialized = false; bool bStakeMinerOutOfSyncWithNetwork = false; bool bDoTally = false; -bool bExecuteGridcoinServices = false; bool bTallyFinished = false; bool bGridcoinGUILoaded = false; diff --git a/src/net.cpp b/src/net.cpp index 964ad19786..46046fbde9 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -29,7 +29,6 @@ using namespace std; bool TallyNetworkAverages(bool ColdBoot); extern void DoTallyResearchAverages(void* parg); -extern void ExecGridcoinServices(void* parg); std::string DefaultWalletAddress(); std::string NodeAddress(CNode* pfrom); @@ -1595,37 +1594,6 @@ void ThreadTallyResearchAverages(void* parg) } - - - -void ThreadExecuteGridcoinServices(void* parg) -{ - RenameThread("grc-services"); - -begin: - try - { - ExecGridcoinServices(parg); - } - catch (bad_alloc ba) - { - printf("\r\nBad Allocation Error in ThreadExecuteGridcoinServices... Recovering \r\n"); - } - catch (std::exception& e) - { - PrintException(&e, "ThreadExecuteGridcoinServices()"); - } - catch(...) - { - printf("Error in ThreadExecuteGridcoinServices... Recovering "); - } - MilliSleep(10000); - if (!fShutdown) printf("Services Exited, Restarting.. \r\n"); - if (!fShutdown) goto begin; -} - - - void BusyWaitForTally() { if (IsLockTimeWithinMinutes(nLastTallyBusyWait,10)) @@ -1678,26 +1646,6 @@ void DoTallyResearchAverages(void* parg) vnThreadsRunning[THREAD_TALLY]--; } - -void ExecGridcoinServices(void* parg) -{ - vnThreadsRunning[THREAD_SERVICES]++; - printf("\r\nStarting dedicated Gridcoin Services thread...\r\n"); - - while (!fShutdown) - { - MilliSleep(5000); - if (bExecuteGridcoinServices) - { - bExecuteGridcoinServices=false; - } - } - vnThreadsRunning[THREAD_SERVICES]--; -} - - - - void ThreadDumpAddress2(void* parg) { vnThreadsRunning[THREAD_DUMPADDRESS]++; @@ -2366,11 +2314,7 @@ void StartNode(void* parg) // Tally network averages if (!NewThread(ThreadTallyResearchAverages, NULL)) printf("Error; NewThread(ThreadTally) failed\n"); - - // Services - if (!NewThread(ThreadExecuteGridcoinServices, NULL)) - printf("Error; NewThread(ThreadExecuteGridcoinServices) failed\r\n"); - + // Mine proof-of-stake blocks in the background if (!GetBoolArg("-staking", true)) printf("Staking disabled\n"); @@ -2411,7 +2355,6 @@ bool StopNode() if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n"); if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n"); if (vnThreadsRunning[THREAD_TALLY] > 0) printf("ThreadTally still running\n"); - if (vnThreadsRunning[THREAD_SERVICES] > 0) printf("ThreadServices still running\n"); if (vnThreadsRunning[THREAD_STAKE_MINER] > 0) printf("ThreadStakeMiner still running\n"); while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0) MilliSleep(20); diff --git a/src/net.h b/src/net.h index 3e25044ce1..179f63a343 100644 --- a/src/net.h +++ b/src/net.h @@ -119,8 +119,7 @@ enum threadId THREAD_DUMPADDRESS, THREAD_RPCHANDLER, THREAD_STAKE_MINER, - THREAD_TALLY, - THREAD_SERVICES, + THREAD_TALLY, THREAD_MAX }; From c949a02436374bc8b57d01a0195054f9397d0ccd Mon Sep 17 00:00:00 2001 From: Marco Nilsson <denravonska@gmail.com> Date: Fri, 6 Oct 2017 13:26:15 +0200 Subject: [PATCH 021/166] Remove checkpoint relaying. This greatly increases synchronization speeds as there are far fewer map lookups when processing blocks. This follows Blackcoin commit 47851b7337f528f52ec20e86dca7dcead8191cf5. --- src/checkpoints.cpp | 465 ++---------------------------------------- src/checkpoints.h | 141 +------------ src/init.cpp | 24 --- src/main.cpp | 155 +------------- src/main.h | 6 - src/rpcblockchain.cpp | 20 +- src/txdb-leveldb.cpp | 26 --- 7 files changed, 29 insertions(+), 808 deletions(-) mode change 100644 => 100755 src/checkpoints.cpp mode change 100644 => 100755 src/init.cpp mode change 100644 => 100755 src/main.cpp mode change 100644 => 100755 src/txdb-leveldb.cpp diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp old mode 100644 new mode 100755 index edb0ec82f4..354efbcd42 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -4,14 +4,13 @@ #include <boost/assign/list_of.hpp> // for 'map_list_of()' #include <boost/range/adaptor/reversed.hpp> + #include "checkpoints.h" + #include "txdb.h" #include "main.h" #include "uint256.h" -double GetGridcoinBalance(std::string SendersGRCAddress); -void SetAdvisory(); -bool InAdvisory(); static const int nCheckpointSpan = 10; @@ -26,8 +25,6 @@ namespace Checkpoints // timestamp before) // + Contains no strange transactions // - - static MapCheckpoints mapCheckpoints = boost::assign::map_list_of ( 0, hashGenesisBlock ) @@ -42,7 +39,7 @@ namespace Checkpoints ( 71000, uint256("0x708c3319912b19c3547fd9a9a2aa6426c3a4543e84f972b3070a24200bd4fcd3") ) ( 85000, uint256("0x928f0669b1f036561a2d53b7588b10c5ea2fcb9e2960a9be593b508a7fcceec1") ) ( 91000, uint256("0x8ed361fa50f6c16fbda4f2c7454dd818f2278151987324825bc1ec1eacfa9be2") ) - (101000, uint256("0x578efd18f7cd5191be3463a2b0db985375f48ee6e8a8940cc6b91d6847fa3614") ) + (101000, uint256("0x578efd18f7cd5191be3463a2b0db985375f48ee6e8a8940cc6b91d6847fa3614") ) (118000, uint256("0x8f8ea6eaeae707ab935b517f1c334e6324df75ad8e5f9fbc4d9fb3cc7aa2e69f") ) (120000, uint256("0xe64d19e39d564cc66e931e88c03207c19e4c9a873ca68ccef16ad712830da726") ) (122000, uint256("0xb35d4f385bba3c3cb3f9b6914edd6621bde8f78c8c42f58ec47131ed6aac82a9") ) @@ -53,15 +50,14 @@ namespace Checkpoints (500000, uint256("0x3916b53eaa0eb392ce5d7e4eaf7db4f745187743f167539ffa4dc1a30c06acbd") ) (700000, uint256("0x2e45c8a834675b505b96792d198c2dc970f560429c635479c347204044acc59b") ) (770000, uint256("0xfc13a63162bc0a5a09acc3f284cf959d6812a027bb54b342a0e1ccaaca8627ce") ) - (850000, uint256("0xc78b15f25ad990d02256907fab92ab37301d129eaea177fd04acacd56c0cbd22") ) - (950000, uint256("0x4be0afdb9273d232de0bc75b572d8bcfaa146d9efdbe4a4f1ab775334f175b0f") ) + (850000, uint256("0xc78b15f25ad990d02256907fab92ab37301d129eaea177fd04acacd56c0cbd22") ) + (950000, uint256("0x4be0afdb9273d232de0bc75b572d8bcfaa146d9efdbe4a4f1ab775334f175b0f") ) ; // TestNet has no checkpoints static MapCheckpoints mapCheckpointsTestnet = - boost::assign::map_list_of - ( 0, hashGenesisBlockTestNet ) - ; + boost::assign::map_list_of + ( 0, hashGenesisBlockTestNet ); bool CheckHardened(int nHeight, const uint256& hash) { @@ -76,6 +72,8 @@ namespace Checkpoints { MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints); + if (checkpoints.empty()) + return 0; return checkpoints.rbegin()->first; } @@ -93,456 +91,23 @@ namespace Checkpoints return NULL; } - // ppcoin: synchronized checkpoint (centrally broadcasted) - uint256 hashSyncCheckpoint = 0; - uint256 hashPendingCheckpoint = 0; - CSyncCheckpoint checkpointMessage; - CSyncCheckpoint checkpointMessagePending; - uint256 hashInvalidCheckpoint = 0; - CCriticalSection cs_hashSyncCheckpoint; - - // ppcoin: get last synchronized checkpoint - CBlockIndex* GetLastSyncCheckpoint() - { - LOCK(cs_hashSyncCheckpoint); - if (!mapBlockIndex.count(hashSyncCheckpoint)) - error("GetSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str()); - else - return mapBlockIndex[hashSyncCheckpoint]; - return NULL; - } - - // ppcoin: only descendant of current sync-checkpoint is allowed - bool ValidateSyncCheckpoint(uint256 hashCheckpoint) - { - if (!mapBlockIndex.count(hashSyncCheckpoint)) - return error("ValidateSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str()); - if (!mapBlockIndex.count(hashCheckpoint)) - return error("ValidateSyncCheckpoint: block index missing for received sync-checkpoint %s", hashCheckpoint.ToString().c_str()); - - CBlockIndex* pindexSyncCheckpoint = mapBlockIndex[hashSyncCheckpoint]; - CBlockIndex* pindexCheckpointRecv = mapBlockIndex[hashCheckpoint]; - - if (pindexCheckpointRecv->nHeight <= pindexSyncCheckpoint->nHeight) - { - // Received an older checkpoint, trace back from current checkpoint - // to the same height of the received checkpoint to verify - // that current checkpoint should be a descendant block - CBlockIndex* pindex = pindexSyncCheckpoint; - while (pindex->nHeight > pindexCheckpointRecv->nHeight) - if (!(pindex = pindex->pprev)) - return error("ValidateSyncCheckpoint: pprev null - block index structure failure"); - if (pindex->GetBlockHash() != hashCheckpoint) - { - if (CHECKPOINT_DISTRIBUTED_MODE==1) SetAdvisory(); - hashInvalidCheckpoint = hashCheckpoint; - return error("ValidateSyncCheckpoint: new sync-checkpoint %s is conflicting with current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); - } - return false; // ignore older checkpoint - } - - // Received checkpoint should be a descendant block of the current - // checkpoint. Trace back to the same height of current checkpoint - // to verify. - CBlockIndex* pindex = pindexCheckpointRecv; - while (pindex->nHeight > pindexSyncCheckpoint->nHeight) - if (!(pindex = pindex->pprev)) - return error("ValidateSyncCheckpoint: pprev2 null - block index structure failure"); - if (pindex->GetBlockHash() != hashSyncCheckpoint) - { - hashInvalidCheckpoint = hashCheckpoint; - if (CHECKPOINT_DISTRIBUTED_MODE==1) SetAdvisory(); - return error("ValidateSyncCheckpoint: new sync-checkpoint %s is not a descendant of current sync-checkpoint %s", hashCheckpoint.ToString().c_str(), hashSyncCheckpoint.ToString().c_str()); - } - return true; - } - - bool WriteSyncCheckpoint(const uint256& hashCheckpoint) - { - CTxDB txdb; - txdb.TxnBegin(); - if (!txdb.WriteSyncCheckpoint(hashCheckpoint)) - { - txdb.TxnAbort(); - return error("WriteSyncCheckpoint(): failed to write to db sync checkpoint %s", hashCheckpoint.ToString().c_str()); - } - if (!txdb.TxnCommit()) - return error("WriteSyncCheckpoint(): failed to commit to db sync checkpoint %s", hashCheckpoint.ToString().c_str()); - - Checkpoints::hashSyncCheckpoint = hashCheckpoint; - return true; - } - - bool AcceptPendingSyncCheckpoint() - { - LOCK(cs_hashSyncCheckpoint); - if (hashPendingCheckpoint != 0 && mapBlockIndex.count(hashPendingCheckpoint)) - { - if (!ValidateSyncCheckpoint(hashPendingCheckpoint)) - { - hashPendingCheckpoint = 0; - checkpointMessagePending.SetNull(); - return false; - } - - CTxDB txdb; - CBlockIndex* pindexCheckpoint = mapBlockIndex[hashPendingCheckpoint]; - if (!pindexCheckpoint->IsInMainChain()) - { - CBlock block; - if (!block.ReadFromDisk(pindexCheckpoint)) - return error("AcceptPendingSyncCheckpoint: ReadFromDisk failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); - if (!block.SetBestChain(txdb, pindexCheckpoint)) - { - hashInvalidCheckpoint = hashPendingCheckpoint; - //SetAdvisory(); - //if (!InAdvisory()) - //{ - return error("AcceptPendingSyncCheckpoint: SetBestChain failed for sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); - //} - } - } - - if (!WriteSyncCheckpoint(hashPendingCheckpoint)) - return error("AcceptPendingSyncCheckpoint(): failed to write sync checkpoint %s", hashPendingCheckpoint.ToString().c_str()); - hashPendingCheckpoint = 0; - checkpointMessage = checkpointMessagePending; - checkpointMessagePending.SetNull(); - printf("AcceptPendingSyncCheckpoint : sync-checkpoint at %s\n", hashSyncCheckpoint.ToString().c_str()); - // relay the checkpoint - if (!checkpointMessage.IsNull()) - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpointMessage.RelayTo(pnode); - } - return true; - } - return false; - } - // Automatically select a suitable sync-checkpoint - uint256 AutoSelectSyncCheckpoint() + const CBlockIndex* AutoSelectSyncCheckpoint() { const CBlockIndex *pindex = pindexBest; // Search backward for a block within max span and maturity window - while (pindex->pprev && (pindex->GetBlockTime() + nCheckpointSpan * GetTargetSpacing(nBestHeight) > pindexBest->GetBlockTime() || pindex->nHeight + nCheckpointSpan > pindexBest->nHeight)) + while (pindex->pprev && pindex->nHeight + nCheckpointSpan > pindexBest->nHeight) pindex = pindex->pprev; - return pindex->GetBlockHash(); + return pindex; } // Check against synchronized checkpoint - bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev) - { - if (fTestNet) return true; // Testnet has no checkpoints - int nHeight = pindexPrev->nHeight + 1; - - LOCK(cs_hashSyncCheckpoint); - // sync-checkpoint should always be accepted block - assert(mapBlockIndex.count(hashSyncCheckpoint)); - const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; - - if (nHeight > pindexSync->nHeight) - { - // trace back to same height as sync-checkpoint - const CBlockIndex* pindex = pindexPrev; - while (pindex->nHeight > pindexSync->nHeight) - if (!(pindex = pindex->pprev)) - return error("CheckSync: pprev null - block index structure failure"); - if (pindex->nHeight < pindexSync->nHeight || pindex->GetBlockHash() != hashSyncCheckpoint) - return false; // only descendant of sync-checkpoint can pass check - } - if (nHeight == pindexSync->nHeight && hashBlock != hashSyncCheckpoint) - return false; // same height with sync-checkpoint - if (nHeight < pindexSync->nHeight && !mapBlockIndex.count(hashBlock)) - return false; // lower height than sync-checkpoint - return true; - } - - bool WantedByPendingSyncCheckpoint(uint256 hashBlock) - { - LOCK(cs_hashSyncCheckpoint); - if (hashPendingCheckpoint == 0) - return false; - if (hashBlock == hashPendingCheckpoint) - return true; - if (mapOrphanBlocks.count(hashPendingCheckpoint) - && hashBlock == WantedByOrphan(mapOrphanBlocks[hashPendingCheckpoint])) - return true; - return false; - } - - // ppcoin: reset synchronized checkpoint to last hardened checkpoint - bool ResetSyncCheckpoint() - { - LOCK(cs_hashSyncCheckpoint); - const uint256& hash = mapCheckpoints.rbegin()->second; - if (mapBlockIndex.count(hash) && !mapBlockIndex[hash]->IsInMainChain()) - { - // checkpoint block accepted but not yet in main chain - printf("ResetSyncCheckpoint: SetBestChain to hardened checkpoint %s\n", hash.ToString().c_str()); - CTxDB txdb; - CBlock block; - if (!block.ReadFromDisk(mapBlockIndex[hash])) - return error("ResetSyncCheckpoint: ReadFromDisk failed for hardened checkpoint %s", hash.ToString().c_str()); - if (!block.SetBestChain(txdb, mapBlockIndex[hash])) - { - return error("ResetSyncCheckpoint: SetBestChain failed for hardened checkpoint %s", hash.ToString().c_str()); - } - } - else if(!mapBlockIndex.count(hash)) - { - // checkpoint block not yet accepted - hashPendingCheckpoint = hash; - checkpointMessagePending.SetNull(); - printf("ResetSyncCheckpoint: pending for sync-checkpoint %s\n", hashPendingCheckpoint.ToString().c_str()); - } - - for (auto const& i : boost::adaptors::reverse(mapCheckpoints)) - { - const uint256& hash = i.second; - if (mapBlockIndex.count(hash) && mapBlockIndex[hash]->IsInMainChain()) - { - if (!WriteSyncCheckpoint(hash)) - return error("ResetSyncCheckpoint: failed to write sync checkpoint %s", hash.ToString().c_str()); - printf("ResetSyncCheckpoint: sync-checkpoint reset to %s\n", hashSyncCheckpoint.ToString().c_str()); - return true; - } - } - - return false; - } - - void AskForPendingSyncCheckpoint(CNode* pfrom) - { - LOCK(cs_hashSyncCheckpoint); - if (pfrom && hashPendingCheckpoint != 0 && (!mapBlockIndex.count(hashPendingCheckpoint)) && (!mapOrphanBlocks.count(hashPendingCheckpoint))) - pfrom->AskFor(CInv(MSG_BLOCK, hashPendingCheckpoint)); - } - - bool SetCheckpointPrivKey(std::string strPrivKey) - { - // Test signing a sync-checkpoint with genesis block - CSyncCheckpoint checkpoint; - printf("Signing Genesis...."); - - checkpoint.hashCheckpoint = !fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet; - CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); - sMsg << (CUnsignedSyncCheckpoint)checkpoint; - checkpoint.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end()); - - std::vector<unsigned char> vchPrivKey = ParseHex(strPrivKey); - CKey key; - key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash - if (!key.Sign(Hash(checkpoint.vchMsg.begin(), checkpoint.vchMsg.end()), checkpoint.vchSig)) - return false; - - // Test signing successful, proceed - CSyncCheckpoint::strMasterPrivKey = strPrivKey; - printf("Signing succeeded\r\n"); - return true; - } - - - bool SendSyncCheckpointWithBalance(uint256 hashCheckpoint, double nBalance, std::string SendingWalletAddress) + bool CheckSync(int nHeight) { - CSyncCheckpoint checkpoint; - checkpoint.hashCheckpoint = hashCheckpoint; - checkpoint.balance = nBalance; - checkpoint.SendingWalletAddress=SendingWalletAddress; - CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); - sMsg << (CUnsignedSyncCheckpoint)checkpoint; - checkpoint.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end()); - if (nBalance < MINIMUM_CHECKPOINT_TRANSMISSION_BALANCE) - { - printf("SendSyncCheckpoint: Balance < 1mil"); - return error("SendSyncCheckpoint: Balance < 1 mil"); - } + const CBlockIndex* pindexSync = AutoSelectSyncCheckpoint(); - if(!checkpoint.ProcessSyncCheckpoint(NULL)) - { - printf("WARNING: SendSyncCheckpoint: Failed to process checkpoint.\n"); + if (nHeight <= pindexSync->nHeight) return false; - } - - // Relay checkpoint - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpoint.RelayTo(pnode); - } - return true; - } - - - - bool SendSyncHashCheckpoint(uint256 hash1, std::string SendingWalletAddress) - { - //11-23-2014 - R HALFORD - Relay Global Checkpoint to all nodes - CSyncCheckpoint checkpoint; - checkpoint.hashCheckpointGlobal = hash1; - checkpoint.hashCheckpoint = hash1; - checkpoint.balance = 0; - checkpoint.SendingWalletAddress=SendingWalletAddress; - CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); - sMsg << (CUnsignedSyncCheckpoint)checkpoint; - checkpoint.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end()); - // Relay checkpoint - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpoint.RelayTo(pnode); - } - printf("Global Sync checkpoint broadcast successfully %s\r\n",checkpoint.hashCheckpointGlobal.GetHex().c_str()); return true; } - - - - bool SendSyncCheckpoint(uint256 hashCheckpoint) - { - CSyncCheckpoint checkpoint; - checkpoint.hashCheckpoint = hashCheckpoint; - CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); - sMsg << (CUnsignedSyncCheckpoint)checkpoint; - checkpoint.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end()); - - if (CSyncCheckpoint::strMasterPrivKey.empty()) - { - printf("SendSyncCheckpoint: Checkpoint Key Unavailable"); - return error("SendSyncCheckpoint: Checkpoint master key unavailable."); - } - - std::vector<unsigned char> vchPrivKey = ParseHex(CSyncCheckpoint::strMasterPrivKey); - - CKey key; - key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash - if (!key.Sign(Hash(checkpoint.vchMsg.begin(), checkpoint.vchMsg.end()), checkpoint.vchSig)) - return error("SendSyncCheckpoint: Unable to sign checkpoint, check private key?"); - - if(!checkpoint.ProcessSyncCheckpoint(NULL)) - { - printf("WARNING: SendSyncCheckpoint: Failed to process checkpoint.\n"); - return false; - } - - // Relay checkpoint - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpoint.RelayTo(pnode); - } - return true; - } - - // Is the sync-checkpoint outside maturity window? - bool IsMatureSyncCheckpoint() - { - LOCK(cs_hashSyncCheckpoint); - // sync-checkpoint should always be accepted block - assert(mapBlockIndex.count(hashSyncCheckpoint)); - const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; - return (nBestHeight >= pindexSync->nHeight + nCoinbaseMaturity || - pindexSync->GetBlockTime() + nStakeMinAge < GetAdjustedTime()); - } -} - - // Gridcoin: sync-checkpoint master key - - const std::string CSyncCheckpoint::strMasterPubKey = "04c858f58b8231219db37e0f714e9884e78ad996ea9ac5d9f72ea969a53e37701374b6348956f3df36fdc10c1e5e4a2a6bded85894ac2f7494700a2d63a4fff772"; - std::string CSyncCheckpoint::strMasterPrivKey = ""; - - - -// ppcoin: verify signature of sync-checkpoint message -bool CSyncCheckpoint::CheckSignature() -{ - CKey key; - if (!key.SetPubKey(ParseHex(CSyncCheckpoint::strMasterPubKey))) - return error("CSyncCheckpoint::CheckSignature() : SetPubKey failed"); - if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) - return error("CSyncCheckpoint::CheckSignature() : verify signature failed"); - - // Now unserialize the data - CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); - sMsg >> *(CUnsignedSyncCheckpoint*)this; - return true; -} - - - // Gridcoin: verify signature of sync-checkpoint message by balance - bool CSyncCheckpoint::CheckSignatureWithBalance() - { - // Verify Senders Balance: - //double senders_balance = GetGridcoinBalance(SendersWalletAddress); - if (balance < 1000000) - { - CKey key; - if (!key.SetPubKey(ParseHex(CSyncCheckpoint::strMasterPubKey))) - return error("CSyncCheckpoint::CheckSignature() : SetPubKey failed"); - if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) - return error("CSyncCheckpoint::CheckSignature() : verify signature failed"); - } - - // Now unserialize the data - CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); - sMsg >> *(CUnsignedSyncCheckpoint*)this; - return true; - } - - -// ppcoin: process synchronized checkpoint -bool CSyncCheckpoint::ProcessSyncCheckpoint(CNode* pfrom) -{ - if (!CheckSignature()) - { - printf("SyncCheckpoint::ProcessSyncCheckpoint::SignatureFailed"); - return false; - } - - LOCK(Checkpoints::cs_hashSyncCheckpoint); - if (!mapBlockIndex.count(hashCheckpoint)) - { - // We haven't received the checkpoint chain, keep the checkpoint as pending - Checkpoints::hashPendingCheckpoint = hashCheckpoint; - Checkpoints::checkpointMessagePending = *this; - printf("ProcessSyncCheckpoint: pending for sync-checkpoint %s\n", hashCheckpoint.ToString().c_str()); - // Ask this guy to fill in what we're missing - if (pfrom) - { - pfrom->PushGetBlocks(pindexBest, hashCheckpoint, true); - // ask directly as well in case rejected earlier by duplicate - // proof-of-stake because getblocks may not get it this time - pfrom->AskFor(CInv(MSG_BLOCK, mapOrphanBlocks.count(hashCheckpoint)? WantedByOrphan(mapOrphanBlocks[hashCheckpoint]) : hashCheckpoint)); - } - return false; - } - - if (!Checkpoints::ValidateSyncCheckpoint(hashCheckpoint)) - return false; - - CTxDB txdb; - CBlockIndex* pindexCheckpoint = mapBlockIndex[hashCheckpoint]; - if (!pindexCheckpoint->IsInMainChain()) - { - // checkpoint chain received but not yet main chain - CBlock block; - if (!block.ReadFromDisk(pindexCheckpoint)) - return error("ProcessSyncCheckpoint: ReadFromDisk failed for sync checkpoint %s", hashCheckpoint.ToString().c_str()); - if (!block.SetBestChain(txdb, pindexCheckpoint)) - { - Checkpoints::hashInvalidCheckpoint = hashCheckpoint; - if (CHECKPOINT_DISTRIBUTED_MODE==1) SetAdvisory(); - return error("ProcessSyncCheckpoint: SetBestChain failed for sync checkpoint %s", hashCheckpoint.ToString().c_str()); - - } - } - - if (!Checkpoints::WriteSyncCheckpoint(hashCheckpoint)) - return error("ProcessSyncCheckpoint(): failed to write sync checkpoint %s", hashCheckpoint.ToString().c_str()); - Checkpoints::checkpointMessage = *this; - Checkpoints::hashPendingCheckpoint = 0; - Checkpoints::checkpointMessagePending.SetNull(); - printf("ProcessSyncCheckpoint: sync-checkpoint at %s\n", hashCheckpoint.ToString().c_str()); - return true; } diff --git a/src/checkpoints.h b/src/checkpoints.h index a2771384d3..33563074ea 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -8,33 +8,14 @@ #include "net.h" #include "util.h" -#ifdef WIN32 -#undef STRICT -#undef PERMISSIVE -#undef ADVISORY -#endif - class uint256; class CBlockIndex; -class CSyncCheckpoint; - /** Block-chain checkpoints are compiled-in sanity checks. * They are updated every release or three. */ namespace Checkpoints { - /** Checkpointing mode */ - enum CPMode - { - // Scrict checkpoints policy, perform conflicts verification and resolve conflicts - STRICT = 0, - // Advisory checkpoints policy, perform conflicts verification but don't try to resolve them - ADVISORY = 1, - // Permissive checkpoints policy, don't perform any checking - PERMISSIVE = 2 - }; - // Returns true if block passes checkpoint checks bool CheckHardened(int nHeight, const uint256& hash); @@ -44,126 +25,8 @@ namespace Checkpoints // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex); - extern uint256 hashSyncCheckpoint; - extern CSyncCheckpoint checkpointMessage; - extern uint256 hashInvalidCheckpoint; - extern CCriticalSection cs_hashSyncCheckpoint; - - CBlockIndex* GetLastSyncCheckpoint(); - bool WriteSyncCheckpoint(const uint256& hashCheckpoint); - bool AcceptPendingSyncCheckpoint(); - uint256 AutoSelectSyncCheckpoint(); - bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev); - bool WantedByPendingSyncCheckpoint(uint256 hashBlock); - bool ResetSyncCheckpoint(); - void AskForPendingSyncCheckpoint(CNode* pfrom); - bool SetCheckpointPrivKey(std::string strPrivKey); - bool SendSyncCheckpoint(uint256 hashCheckpoint); - bool SendSyncCheckpointWithBalance(uint256 hashCheckpoint, double nBalance, std::string SendingWalletAddress); - bool SendSyncHashCheckpoint(uint256 hash1, std::string SendingWalletAddress); - - bool IsMatureSyncCheckpoint(); + const CBlockIndex* AutoSelectSyncCheckpoint(); + bool CheckSync(int nHeight); } -// ppcoin: synchronized checkpoint -class CUnsignedSyncCheckpoint -{ -public: - int nVersion; - uint256 hashCheckpoint; // checkpoint block - double balance; - std::string SendingWalletAddress; - std::string SendersWalletAddress; - uint256 hashCheckpointGlobal; - - IMPLEMENT_SERIALIZE - ( - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(hashCheckpoint); - READWRITE(balance); - READWRITE(SendingWalletAddress); - READWRITE(hashCheckpointGlobal); - ) - - void SetNull() - { - nVersion = 1; - hashCheckpoint = 0; - } - - std::string ToString() const - { - return strprintf( - "CSyncCheckpoint(\n" - " nVersion = %d\n" - " hashCheckpoint = %s\n" - ")\n", - nVersion, - hashCheckpoint.ToString().c_str()); - } - - void print() const - { - printf("%s", ToString().c_str()); - } -}; - -class CSyncCheckpoint : public CUnsignedSyncCheckpoint -{ -public: - static const std::string strMasterPubKey; - static std::string strMasterPrivKey; - - std::vector<unsigned char> vchMsg; - std::vector<unsigned char> vchSig; - - CSyncCheckpoint() - { - SetNull(); - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(vchMsg); - READWRITE(vchSig); - READWRITE(balance); - READWRITE(SendingWalletAddress); - READWRITE(hashCheckpointGlobal); - ) - - void SetNull() - { - CUnsignedSyncCheckpoint::SetNull(); - vchMsg.clear(); - vchSig.clear(); - } - - bool IsNull() const - { - return (hashCheckpoint == 0); - } - - uint256 GetHash() const - { - return SerializeHash(*this); - } - - bool RelayTo(CNode* pnode) const - { - // returns true if wasn't already sent - if (pnode->hashCheckpointKnown != hashCheckpoint) - { - pnode->hashCheckpointKnown = hashCheckpoint; - pnode->PushMessage("checkpoint", *this); - return true; - } - return false; - } - - bool CheckSignature(); - bool CheckSignatureWithBalance(); - bool ProcessSyncCheckpoint(CNode* pfrom); -}; - #endif diff --git a/src/init.cpp b/src/init.cpp old mode 100644 new mode 100755 index d7cfe069e2..5f295b54b5 --- a/src/init.cpp +++ b/src/init.cpp @@ -9,7 +9,6 @@ #include "init.h" #include "util.h" #include "ui_interface.h" -#include "checkpoints.h" #include <boost/filesystem.hpp> #include <boost/filesystem/fstream.hpp> #include <boost/filesystem/convenience.hpp> @@ -49,7 +48,6 @@ extern unsigned int nNodeLifespan; extern unsigned int nDerivationMethodIndex; extern unsigned int nMinerSleep; extern bool fUseFastIndex; -extern enum Checkpoints::CPMode CheckpointsMode; void InitializeBoincProjects(); @@ -363,7 +361,6 @@ std::string HelpMessage() " -bind=<addr> " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" + " -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" + " -synctime " + _("Sync time with other nodes. Disable if time on your system is precise e.g. syncing with NTP (default: 1)") + "\n" + - " -cppolicy " + _("Sync checkpoints policy (default: strict)") + "\n" + " -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" + " -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" + " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)") + "\n" + @@ -534,21 +531,6 @@ bool AppInit2() fUseFastIndex = GetBoolArg("-fastindex", false); nMinerSleep = GetArg("-minersleep", 8000); - - CheckpointsMode = Checkpoints::STRICT; - //CheckpointsMode = Checkpoints::ADVISORY; - - std::string strCpMode = GetArg("-cppolicy", "strict"); - - if(strCpMode == "strict") - CheckpointsMode = Checkpoints::STRICT; - - if(strCpMode == "advisory") - CheckpointsMode = Checkpoints::ADVISORY; - - if(strCpMode == "permissive") - CheckpointsMode = Checkpoints::PERMISSIVE; - nDerivationMethodIndex = 0; fTestNet = GetBoolArg("-testnet"); @@ -873,12 +855,6 @@ bool AppInit2() } } - if (mapArgs.count("-checkpointkey")) // ppcoin: checkpoint master priv key - { - if (!Checkpoints::SetCheckpointPrivKey(GetArg("-checkpointkey", ""))) - InitError(_("Unable to sign checkpoint, wrong checkpointkey?\n")); - } - for (auto const& strDest : mapMultiArgs["-seednode"]) AddOneShot(strDest); diff --git a/src/main.cpp b/src/main.cpp old mode 100644 new mode 100755 index c90efb2ddd..3d9af5e132 --- a/src/main.cpp +++ b/src/main.cpp @@ -149,9 +149,7 @@ extern std::string ExtractHTML(std::string HTMLdata, std::string tagstartprefix, CTxMemPool mempool; unsigned int nTransactionsUpdated = 0; unsigned int REORGANIZE_FAILED = 0; - unsigned int WHITELISTED_PROJECTS = 0; -unsigned int CHECKPOINT_VIOLATIONS = 0; int64_t nLastTallied = 0; int64_t nLastPing = 0; int64_t nLastPeek = 0; @@ -189,8 +187,6 @@ json_spirit::Array MagnitudeReportCSV(bool detail); int64_t nLastBlockSolved = 0; //Future timestamp int64_t nLastBlockSubmitted = 0; -uint256 muGlobalCheckpointHash = 0; -uint256 muGlobalCheckpointHashRelayed = 0; ///////////////////////MINOR VERSION//////////////////////////////// std::string msMasterProjectPublicKey = "049ac003b3318d9fe28b2830f6a95a2624ce2a69fb0c0c7ac0b513efcc1e93a6a6e8eba84481155dd82f2f1104e0ff62c69d662b0094639b7106abc5d84f948c0a"; // The Private Key is revealed by design, for public messages only: @@ -262,7 +258,6 @@ std::map<std::string, StructCPID> mvDPORCopy; std::map<std::string, StructCPID> mvResearchAge; std::map<std::string, HashSet> mvCPIDBlockHashes; -enum Checkpoints::CPMode CheckpointsMode; BlockFinder blockFinder; // Gridcoin - Rob Halford @@ -3506,19 +3501,6 @@ bool ForceReorganizeToHash(uint256 NewHash) return true; } - - -void SetAdvisory() -{ - CheckpointsMode = Checkpoints::ADVISORY; - -} - -bool InAdvisory() -{ - return (CheckpointsMode == Checkpoints::ADVISORY); -} - // Called from inside SetBestChain: attaches a block to the new best chain being built bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew, bool fReorganizing) { @@ -4119,39 +4101,14 @@ bool CBlock::AcceptBlock(bool generated_by_me) //Grandfather if (nHeight > nGrandfather) { - bool cpSatisfies = Checkpoints::CheckSync(hash, pindexPrev); - // Check that the block satisfies synchronized checkpoint - if (CheckpointsMode == Checkpoints::STRICT && !cpSatisfies) - { - if (CHECKPOINT_DISTRIBUTED_MODE==1) - { - CHECKPOINT_VIOLATIONS++; - if (CHECKPOINT_VIOLATIONS > 3) - { - //For stability, move the client into ADVISORY MODE: - printf("Moving Gridcoin into Checkpoint ADVISORY mode.\r\n"); - CheckpointsMode = Checkpoints::ADVISORY; - } - } - return error("AcceptBlock() : rejected by synchronized checkpoint"); - } - - if (CheckpointsMode == Checkpoints::ADVISORY && !cpSatisfies) - strMiscWarning = _("WARNING: synchronized checkpoint violation detected, but skipped!"); - - if (CheckpointsMode == Checkpoints::ADVISORY && cpSatisfies && CHECKPOINT_DISTRIBUTED_MODE==1) - { - ///Move the client back into STRICT mode - CHECKPOINT_VIOLATIONS = 0; - printf("Moving Gridcoin into Checkpoint STRICT mode.\r\n"); - strMiscWarning = ""; - CheckpointsMode = Checkpoints::STRICT; - } + // Check that the block chain matches the known block chain up to a checkpoint + if (!Checkpoints::CheckHardened(nHeight, hash)) + return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lock-in at %d", nHeight)); // Enforce rule that the coinbase starts with serialized block height CScript expect = CScript() << nHeight; if (vtx[0].vin[0].scriptSig.size() < expect.size() || - !std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) + !std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) return DoS(100, error("AcceptBlock() : block height mismatch in coinbase")); } @@ -4175,8 +4132,6 @@ bool CBlock::AcceptBlock(bool generated_by_me) pnode->PushInventory(CInv(MSG_BLOCK, hash)); } - // ppcoin: check pending sync-checkpoint - Checkpoints::AcceptPendingSyncCheckpoint(); if (fDebug) printf("{ACC}"); nLastAskedForBlocks=GetAdjustedTime(); ResetTimerMain("OrphanBarrage"); @@ -4611,35 +4566,28 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) // ppcoin: check proof-of-stake // Limited duplicity on stake: prevents block flood attack // Duplicate stake allowed only when there is orphan child block - if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash) && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash)) return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str()); - CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint(); - if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + if (pblock->hashPrevBlock != hashBestChain) { // Extra checks to prevent "fill up memory by spamming with bogus blocks" + const CBlockIndex* pcheckpoint = Checkpoints::AutoSelectSyncCheckpoint(); int64_t deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime; - if (deltaTime < -10*60) + if (deltaTime < 0) { if (pfrom) pfrom->Misbehaving(1); return error("ProcessBlock() : block with timestamp before last checkpoint"); } - - } // Preliminary checks if (!pblock->CheckBlock("ProcessBlock", pindexBest->nHeight, 100*COIN)) return error("ProcessBlock() : CheckBlock FAILED"); - // ppcoin: ask for pending sync-checkpoint if any - if (!IsInitialBlockDownload()) - Checkpoints::AskForPendingSyncCheckpoint(pfrom); - - // If don't already have its previous block, shunt it off to holding area until we get it if (!mapBlockIndex.count(pblock->hashPrevBlock)) { @@ -4677,8 +4625,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) // Limited duplicity on stake: prevents block flood attack // Duplicate stake allowed only when there is orphan child block if (setStakeSeenOrphan.count(pblock->GetProofOfStake()) && - !mapOrphanBlocksByPrev.count(hash) && - !Checkpoints::WantedByPendingSyncCheckpoint(hash)) + !mapOrphanBlocksByPrev.count(hash)) return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, @@ -4730,9 +4677,6 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) } - - // if responsible for sync-checkpoint send it - if (false && pfrom && !CSyncCheckpoint::strMasterPrivKey.empty()) Checkpoints::SendSyncCheckpoint(Checkpoints::AutoSelectSyncCheckpoint()); printf("{PB}: ACC; \r\n"); GridcoinServices(); return true; @@ -4959,25 +4903,6 @@ bool LoadBlockIndex(bool fAllowNew) return error("LoadBlockIndex() : writing genesis block to disk failed"); if (!block.AddToBlockIndex(nFile, nBlockPos, hashGenesisBlock)) return error("LoadBlockIndex() : genesis block not accepted"); - - // ppcoin: initialize synchronized checkpoint - if (!Checkpoints::WriteSyncCheckpoint((!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet))) - return error("LoadBlockIndex() : failed to init sync checkpoint"); - } - - string strPubKey = ""; - - // if checkpoint master key changed must reset sync-checkpoint - if (!txdb.ReadCheckpointPubKey(strPubKey) || strPubKey != CSyncCheckpoint::strMasterPubKey) - { - // write checkpoint master key to db - txdb.TxnBegin(); - if (!txdb.WriteCheckpointPubKey(CSyncCheckpoint::strMasterPubKey)) - return error("LoadBlockIndex() : failed to write new checkpoint master key to db"); - if (!txdb.TxnCommit()) - return error("LoadBlockIndex() : failed to commit new checkpoint master key to db"); - if ((!fTestNet) && !Checkpoints::ResetSyncCheckpoint()) - return error("LoadBlockIndex() : failed to reset sync-checkpoint"); } return true; @@ -5935,23 +5860,6 @@ string GetWarnings(string strFor) strStatusBar = strMiscWarning; } - // if detected invalid checkpoint enter safe mode - if (Checkpoints::hashInvalidCheckpoint != 0) - { - if (CHECKPOINT_DISTRIBUTED_MODE==1) - { - //10-18-2014-Halford- If invalid checkpoint found, reboot the node: - printf("Moving Gridcoin into Checkpoint ADVISORY mode.\r\n"); - CheckpointsMode = Checkpoints::ADVISORY; - } - else - { - nPriority = 3000; - strStatusBar = strRPC = _("WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers."); - printf("WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers."); - } - } - // Alerts { LOCK(cs_mapAlerts); @@ -6400,23 +6308,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, item.second.RelayTo(pfrom); } - // Relay sync-checkpoint - { - LOCK(Checkpoints::cs_hashSyncCheckpoint); - if (!Checkpoints::checkpointMessage.IsNull()) - Checkpoints::checkpointMessage.RelayTo(pfrom); - } - pfrom->fSuccessfullyConnected = true; if (fDebug10) printf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str()); cPeerBlockCounts.input(pfrom->nStartingHeight); - - // ppcoin: ask for pending sync-checkpoint if any - if (!IsInitialBlockDownload()) - Checkpoints::AskForPendingSyncCheckpoint(pfrom); } else if (pfrom->nVersion == 0) { @@ -6669,40 +6566,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } } - else if (strCommand == "checkpoint") - { - CSyncCheckpoint checkpoint; - vRecv >> checkpoint; - //Checkpoint received from node with more than 1 Million GRC: - if (CHECKPOINT_DISTRIBUTED_MODE==0 || CHECKPOINT_DISTRIBUTED_MODE==1) - { - if (checkpoint.ProcessSyncCheckpoint(pfrom)) - { - // Relay - pfrom->hashCheckpointKnown = checkpoint.hashCheckpoint; - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - checkpoint.RelayTo(pnode); - } - } - else if (CHECKPOINT_DISTRIBUTED_MODE == 2) - { - // R HALFORD: One of our global GRC nodes solved a PoR block, store the last blockhash in memory - muGlobalCheckpointHash = checkpoint.hashCheckpointGlobal; - // Relay - pfrom->hashCheckpointKnown = checkpoint.hashCheckpointGlobal; - //Prevent broadcast storm: If not broadcast yet, relay the checkpoint globally: - if (muGlobalCheckpointHashRelayed != checkpoint.hashCheckpointGlobal && checkpoint.hashCheckpointGlobal != 0) - { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - { - checkpoint.RelayTo(pnode); - } - } - } - } - else if (strCommand == "getheaders") { CBlockLocator locator; diff --git a/src/main.h b/src/main.h index 29e4f3dcc1..c65bbcf08f 100755 --- a/src/main.h +++ b/src/main.h @@ -29,10 +29,6 @@ class CTxMemPool; static const int LAST_POW_BLOCK = 2050; extern unsigned int REORGANIZE_FAILED; extern unsigned int WHITELISTED_PROJECTS; -extern unsigned int CHECKPOINT_VIOLATIONS; -static const int MAX_NEWBIE_BLOCKS = 200; -static const int MAX_NEWBIE_BLOCKS_LEVEL2 = 500; -static const int CHECKPOINT_DISTRIBUTED_MODE = 50; static const int CONSENSUS_LOOKBACK = 5; //Amount of blocks to go back from best block, to avoid counting forked blocks static const int BLOCK_GRANULARITY = 10; //Consensus block divisor @@ -41,7 +37,6 @@ static const double NeuralNetworkMultiplier = 115000; extern int64_t nLastBlockSolved; extern int64_t nLastBlockSubmitted; -extern uint256 muGlobalCheckpointHashRelayed; extern std::string msMasterProjectPublicKey; extern std::string msMasterMessagePublicKey; extern std::string msMasterMessagePrivateKey; @@ -71,7 +66,6 @@ static const int64_t MAX_MONEY = 2000000000 * COIN; inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } /** Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. */ static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC -static const unsigned int MINIMUM_CHECKPOINT_TRANSMISSION_BALANCE = 4000000; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index fe8e2f8cd3..b7d5721461 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -138,7 +138,6 @@ double CoinToDouble(double surrogate); int64_t GetRSAWeightByCPID(std::string cpid); double GetUntrustedMagnitude(std::string cpid, double& out_owed); extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry); -extern enum Checkpoints::CPMode CheckpointsMode; int ReindexWallet(); extern Array MagnitudeReportCSV(bool detail); std::string getfilecontents(std::string filename); @@ -4380,25 +4379,12 @@ Value getcheckpoint(const Array& params, bool fHelp) "Show info of synchronized checkpoint.\n"); Object result; - CBlockIndex* pindexCheckpoint; + const CBlockIndex* pindexCheckpoint = Checkpoints::AutoSelectSyncCheckpoint(); - result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str())); - pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint]; + result.push_back(Pair("synccheckpoint", pindexCheckpoint->GetBlockHash().ToString().c_str())); result.push_back(Pair("height", pindexCheckpoint->nHeight)); result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str())); - - // Check that the block satisfies synchronized checkpoint - if (CheckpointsMode == Checkpoints::STRICT) - result.push_back(Pair("policy", "strict")); - - if (CheckpointsMode == Checkpoints::ADVISORY) - result.push_back(Pair("policy", "advisory")); - - if (CheckpointsMode == Checkpoints::PERMISSIVE) - result.push_back(Pair("policy", "permissive")); - - if (mapArgs.count("-checkpointkey")) - result.push_back(Pair("checkpointmaster", true)); + result.push_back(Pair("policy", "rolling")); return result; } diff --git a/src/txdb-leveldb.cpp b/src/txdb-leveldb.cpp old mode 100644 new mode 100755 index 251a4b5b96..bcdace9c70 --- a/src/txdb-leveldb.cpp +++ b/src/txdb-leveldb.cpp @@ -14,7 +14,6 @@ #include <memenv/memenv.h> #include "kernel.h" -#include "checkpoints.h" #include "txdb.h" #include "util.h" #include "main.h" @@ -279,26 +278,6 @@ bool CTxDB::WriteBestInvalidTrust(CBigNum bnBestInvalidTrust) return Write(string("bnBestInvalidTrust"), bnBestInvalidTrust); } -bool CTxDB::ReadSyncCheckpoint(uint256& hashCheckpoint) -{ - return Read(string("hashSyncCheckpoint"), hashCheckpoint); -} - -bool CTxDB::WriteSyncCheckpoint(uint256 hashCheckpoint) -{ - return Write(string("hashSyncCheckpoint"), hashCheckpoint); -} - -bool CTxDB::ReadCheckpointPubKey(string& strPubKey) -{ - return Read(string("strCheckpointPubKey"), strPubKey); -} - -bool CTxDB::WriteCheckpointPubKey(const string& strPubKey) -{ - return Write(string("strCheckpointPubKey"), strPubKey); -} - bool CTxDB::ReadGenericData(std::string KeyName, std::string& strValue) { return Read(string(KeyName.c_str()), strValue); @@ -478,11 +457,6 @@ bool CTxDB::LoadBlockIndex() hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, CBigNum(nBestChainTrust).ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); - // NovaCoin: 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); From 2e9cc953e7ef10af9e2d3bf9700b914c4b1bc694 Mon Sep 17 00:00:00 2001 From: Paul Jensen <eastendmumbles@gmail.com> Date: Fri, 6 Oct 2017 09:41:09 -0700 Subject: [PATCH 022/166] Change int64_t nCoinAge to uint64_t --- src/main.cpp | 12 ++++++------ src/main.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c90efb2ddd..1e7754803a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1904,7 +1904,7 @@ double GetMagnitudeMultiplier(int64_t nTime) } -int64_t GetProofOfStakeMaxReward(int64_t nCoinAge, int64_t nFees, int64_t locktime) +int64_t GetProofOfStakeMaxReward(uint64_t nCoinAge, int64_t nFees, int64_t locktime) { int64_t nInterest = nCoinAge * GetCoinYearReward(locktime) * 33 / (365 * 33 + 8); nInterest += 10*COIN; @@ -1951,7 +1951,7 @@ double GetProofOfResearchReward(std::string cpid, bool VerifyingBlock) // miner's coin stake reward based on coin age spent (coin-days) -int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees, std::string cpid, +int64_t GetProofOfStakeReward(uint64_t nCoinAge, int64_t nFees, std::string cpid, bool VerifyingBlock, int VerificationPhase, int64_t nTime, CBlockIndex* pindexLast, std::string operation, double& OUT_POR, double& OUT_INTEREST, double& dAccrualAge, double& dMagnitudeUnit, double& AvgMagnitude) { @@ -1964,7 +1964,7 @@ int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees, std::string cpid, int64_t nSubsidy = nInterest + nBoinc; if (fDebug10 || GetBoolArg("-printcreation")) { - printf("GetProofOfStakeReward(): create=%s nCoinAge=%" PRId64 " nBoinc=%" PRId64 " \n", + printf("GetProofOfStakeReward(): create=%s nCoinAge=%" PRIu64 " nBoinc=%" PRId64 " \n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBoinc); } int64_t maxStakeReward1 = GetProofOfStakeMaxReward(nCoinAge, nFees, nTime); @@ -2004,7 +2004,7 @@ int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees, std::string cpid, if (fDebug10 || GetBoolArg("-printcreation")) { - printf("GetProofOfStakeReward(): create=%s nCoinAge=%" PRId64 " nBoinc=%" PRId64 " \n", + printf("GetProofOfStakeReward(): create=%s nCoinAge=%" PRIu64 " nBoinc=%" PRId64 " \n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBoinc); } @@ -3752,7 +3752,7 @@ bool CBlock::GetCoinAge(uint64_t& nCoinAge) const if (nCoinAge == 0) // block coin age minimum 1 coin-day nCoinAge = 1; if (fDebug && GetBoolArg("-printcoinage")) - printf("block coin age total nCoinDays=%" PRId64 "\n", nCoinAge); + printf("block coin age total nCoinDays=%" PRIu64 "\n", nCoinAge); return true; } @@ -3865,7 +3865,7 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh double dAccrualAge = 0; double dMagnitudeUnit = 0; double dAvgMagnitude = 0; - int64_t nCoinAge = 0; + uint64_t nCoinAge = 0; int64_t nFees = 0; if (bb.cpid != "INVESTOR" && IsProofOfStake() && height1 > nGrandfather && IsResearchAgeEnabled(height1) && BlockNeedsChecked(nTime) && !fLoadingIndex) diff --git a/src/main.h b/src/main.h index 29e4f3dcc1..bb6f27b7cf 100755 --- a/src/main.h +++ b/src/main.h @@ -259,7 +259,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS int64_t GetProofOfWorkReward(int64_t nFees, int64_t locktime, int64_t height); int64_t ComputeResearchAccrual(int64_t nTime, std::string cpid, std::string operation, CBlockIndex* pindexLast, bool bVerifyingBlock, int VerificationPhase, double& dAccrualAge, double& dMagnitudeUnit, double& AvgMagnitude); -int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees, std::string cpid, +int64_t GetProofOfStakeReward(uint64_t nCoinAge, int64_t nFees, std::string cpid, bool VerifyingBlock, int VerificationPhase, int64_t nTime, CBlockIndex* pindexLast, std::string operation, double& OUT_POR, double& OUT_INTEREST, double& dAccrualAge, double& dMagnitudeUnit, double& AvgMagnitude); From 76469d873ced9e3b7a04155084667c11492236e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= <tomasbrod@azet.sk> Date: Sun, 3 Sep 2017 09:41:01 +0200 Subject: [PATCH 023/166] Save transaction id for Messages. --- src/main.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c90efb2ddd..06f37575a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8388,8 +8388,10 @@ std::string GetOrgSymbolFromFeedKey(std::string feedkey) -bool MemorizeMessage(std::string msg, int64_t nTime, double dAmount, std::string sRecipient) +bool MemorizeMessage(const CTransaction &tx, double dAmount, std::string sRecipient) { + const std::string &msg = tx.hashBoinc; + const int64_t &nTime = tx.nTime; if (msg.empty()) return false; bool fMessageLoaded = false; @@ -8493,6 +8495,8 @@ bool MemorizeMessage(std::string msg, int64_t nTime, double dAmount, std::string fMessageLoaded = true; } + WriteCache(sMessageType,sMessageKey+";TrxID",tx.GetHash().GetHex(),nTime); + } } @@ -8814,7 +8818,7 @@ bool LoadAdminMessages(bool bFullTableScan, std::string& out_errors) sRecipient = PubKeyToAddress(tx.vout[i].scriptPubKey); dAmount += CoinToDouble(tx.vout[i].nValue); } - MemorizeMessage(tx.hashBoinc,tx.nTime,dAmount,sRecipient); + MemorizeMessage(tx,dAmount,sRecipient); } iPos++; } From 089b639dafccddf769de4a175fff0942dd05ac12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= <tomasbrod@azet.sk> Date: Sat, 7 Oct 2017 10:45:44 +0200 Subject: [PATCH 024/166] Added sendrawcontract command. --- src/rpcblockchain.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index fe8e2f8cd3..6a0aa617ed 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -2214,6 +2214,29 @@ Value execute(const Array& params, bool fHelp) results.push_back(entry); } } + else if (sItem == "sendrawcontract") + { + if (params.size() != 2) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "You must specify raw contract."); + if (pwalletMain->IsLocked()) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); + std::string sAddress = GetBurnAddress(); + CBitcoinAddress address(sAddress); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address"); + std::string sContract = params[1].get_str(); + entry.push_back(Pair("Contract",sContract)); + entry.push_back(Pair("Recipient",sAddress)); + int64_t nAmount = CENT; + // Wallet comments + CWalletTx wtx; + wtx.hashBoinc = sContract; + string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx, false); + if (!strError.empty()) + throw JSONRPCError(RPC_WALLET_ERROR, strError); + entry.push_back(Pair("TrxID",wtx.GetHash().GetHex())); + results.push_back(entry); + } else if (sItem == "memorizekeys") { std::string sOut = ""; From f83920bb4885e988c85a32a798dc8fea01518106 Mon Sep 17 00:00:00 2001 From: Marco Nilsson <denravonska@gmail.com> Date: Sat, 7 Oct 2017 15:16:53 +0200 Subject: [PATCH 025/166] Apply predicate on all appcache items, not just the first. The implementation got a bit more convoluted than I would have liked, but it still allows us to use ranged based for loops. Since everything moved to the header there is currently no need for the cpp. Once the appcache accesses are fully encapsulated we can bring the cpp back. This closes #682. --- gridcoinresearch.pro | 3 +-- src/Makefile.include.objs | 3 +-- src/appcache.cpp | 28 -------------------- src/appcache.h | 55 +++++++++++++++++++-------------------- src/rpcblockchain.cpp | 16 ++++++------ 5 files changed, 37 insertions(+), 68 deletions(-) delete mode 100644 src/appcache.cpp diff --git a/gridcoinresearch.pro b/gridcoinresearch.pro index 52282ce9af..82702155e2 100755 --- a/gridcoinresearch.pro +++ b/gridcoinresearch.pro @@ -352,8 +352,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/upgrader.cpp \ src/boinc.cpp \ src/allocators.cpp \ - src/backup.cpp \ - src/appcache.cpp + src/backup.cpp ## #RC_FILE = qaxserver.rc diff --git a/src/Makefile.include.objs b/src/Makefile.include.objs index 8d4aa43755..656643feea 100755 --- a/src/Makefile.include.objs +++ b/src/Makefile.include.objs @@ -39,5 +39,4 @@ OBJS= \ obj/beacon.o \ obj/boinc.o \ obj/allocators.o \ - obj/backup.o \ - obj/appcache.o + obj/backup.o diff --git a/src/appcache.cpp b/src/appcache.cpp deleted file mode 100644 index 783317bd29..0000000000 --- a/src/appcache.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "appcache.h" -#include "main.h" - -#include <boost/algorithm/string.hpp> -#include <algorithm> - -AppCacheIterator::AppCacheIterator(const std::string& key) - : _begin(mvApplicationCache.begin()) - , _end(mvApplicationCache.end()) -{ - auto predicate = [key](typename AppCache::const_reference t) - { - return boost::algorithm::starts_with(t.first, key); - }; - - // Find the first occurrence of 'key' - _begin = std::find_if(_begin, _end, predicate); -} - -AppCache::iterator AppCacheIterator::begin() -{ - return _begin; -} - -AppCache::iterator AppCacheIterator::end() -{ - return _end; -} diff --git a/src/appcache.h b/src/appcache.h index 6dca2a3163..9dbc421e71 100644 --- a/src/appcache.h +++ b/src/appcache.h @@ -2,12 +2,31 @@ #include <string> #include <map> +#include <boost/algorithm/string.hpp> +#include <boost/iterator/filter_iterator.hpp> //! //! \brief Application cache type. //! typedef std::map<std::string, std::string> AppCache; +// Predicate +struct AppCacheMatches +{ + AppCacheMatches(const std::string& needle) + : needle(needle) + {} + + bool operator()(const AppCache::value_type& t) + { + return boost::algorithm::starts_with(t.first, needle); + }; + + std::string needle; +}; + +typedef boost::filter_iterator<AppCacheMatches, AppCache::iterator> filter_iterator; + //! //! \brief Application cache data key iterator. //! @@ -16,37 +35,17 @@ typedef std::map<std::string, std::string> AppCache; //! all the cached polls: //! //! \code -//! for(const auto& item : AppCacheIterator("poll") +//! for(const auto& item : AppCacheFilter("poll") //! { //! const std::string& poll_name = item.second; //! } //! \endcode //! -class AppCacheIterator +boost::iterator_range<filter_iterator> AppCacheFilter(const std::string& needle) { -public: - //! - //! \brief Constructor. - //! \param key Key to search for. For legacy code compatibility reasons - //! \p key is matched to the start of the cached key, so \a poll will - //! iterate over items with the key \a polls as well. - //! - AppCacheIterator(const std::string& key); - - //! - //! \brief Get iterator to first matching element. - //! \return Iterator pointing to the first matching element, or end() - //! if none is found. - //! - AppCache::iterator begin(); - - //! - //! \brief Get iterator to the element after the last element. - //! \return End iterator element. - //! - AppCache::iterator end(); - -private: - AppCache::iterator _begin; - AppCache::iterator _end; -}; + auto pred = AppCacheMatches(needle); + auto begin = boost::make_filter_iterator(pred, mvApplicationCache.begin(), mvApplicationCache.end()); + auto end = boost::make_filter_iterator(pred, mvApplicationCache.end(), mvApplicationCache.end()); + return boost::make_iterator_range(begin, end); +} + diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index fe8e2f8cd3..796a6fed1d 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -874,7 +874,7 @@ double GetCountOf(std::string datatype) std::string GetListOf(std::string datatype) { std::string rows; - for(const auto& item : AppCacheIterator(datatype)) + for(const auto& item : AppCacheFilter(datatype)) { const std::string& key_name = item.first; const std::string& key_value = item.second; @@ -2301,7 +2301,7 @@ Value execute(const Array& params, bool fHelp) { std::string sType = params[1].get_str(); entry.push_back(Pair("Key Type",sType)); - for(const auto& item : AppCacheIterator(sType)) + for(const auto& item : AppCacheFilter(sType)) entry.push_back(Pair(item.first, item.second)); results.push_back(entry); @@ -2820,7 +2820,7 @@ std::string SignBlockWithCPID(std::string sCPID, std::string sBlockHash) std::string GetPollContractByTitle(std::string objecttype, std::string title) { - for(const auto& item : AppCacheIterator(objecttype)) + for(const auto& item : AppCacheFilter(objecttype)) { const std::string& contract = item.second; const std::string& PollTitle = ExtractXML(contract,"<TITLE>",""); @@ -2919,7 +2919,7 @@ double VotesCount(std::string pollname, std::string answer, double sharetype, do double MoneySupplyFactor = GetMoneySupplyFactor(); - for(const auto& item : AppCacheIterator("vote")) + for(const auto& item : AppCacheFilter("vote")) { const std::string& contract = item.second; const std::string& Title = ExtractXML(contract,"",""); @@ -3393,7 +3393,7 @@ Array GetJsonVoteDetailsReport(std::string pollname) entry.push_back(Pair("GRCAddress,CPID,Question,Answer,ShareType,URL", "Shares")); boost::to_lower(pollname); - for(const auto& item : AppCacheIterator("vote")) + for(const auto& item : AppCacheFilter("vote")) { const std::string& contract = item.second; const std::string& Title = ExtractXML(contract,"",""); @@ -3446,7 +3446,7 @@ Array GetJSONPollsReport(bool bDetail, std::string QueryByTitle, std::string& ou std::string sExportRow; out_export.clear(); - for(const auto& item : AppCacheIterator(datatype)) + for(const auto& item : AppCacheFilter(datatype)) { const std::string& key_name = item.first; const std::string& contract = item.second; @@ -3540,7 +3540,7 @@ Array GetUpgradedBeaconReport() std::string row = ""; int iBeaconCount = 0; int iUpgradedBeaconCount = 0; - for(const auto& item : AppCacheIterator(datatype)) + for(const auto& item : AppCacheFilter(datatype)) { const std::string& key_name = item.first; const std::string& key_value = item.second; @@ -3572,7 +3572,7 @@ Array GetJSONBeaconReport() entry.push_back(Pair("CPID","GRCAddress")); std::string datatype="beacon"; std::string row; - for(const auto& item : AppCacheIterator(datatype)) + for(const auto& item : AppCacheFilter(datatype)) { const std::string& key_name = item.first; const std::string& key_value = item.second; From 34a7ccf6ecc290a240f59a7275ea8bf8280f0ff8 Mon Sep 17 00:00:00 2001 From: Acey Date: Sat, 7 Oct 2017 22:33:14 +0900 Subject: [PATCH 026/166] doc/bitcoin_logo_doxygen.png and doc/Doxyfile are obsolete (#670) Remove unused Doxygen. --- doc/Doxyfile | 1752 ---------------------------------- doc/bitcoin_logo_doxygen.png | Bin 5445 -> 0 bytes 2 files changed, 1752 deletions(-) delete mode 100644 doc/Doxyfile delete mode 100644 doc/bitcoin_logo_doxygen.png diff --git a/doc/Doxyfile b/doc/Doxyfile deleted file mode 100644 index 08d4f8c37f..0000000000 --- a/doc/Doxyfile +++ /dev/null @@ -1,1752 +0,0 @@ -# Doxyfile 1.7.4 - -# !!! Invoke doxygen from project root using: -# doxygen doc/Doxyfile - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = Bitcoin - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 0.5.0 - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = "P2P Digital Currency" - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = doc/bitcoin_logo_doxygen.png - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc/doxygen - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = src - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py \ - *.f90 \ - *.f \ - *.for \ - *.vhd \ - *.vhdl - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is adviced to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called Helvetica to the output -# directory and reference it in all dot files that doxygen generates. -# When you want a differently looking font you can specify the font name -# using DOT_FONTNAME. You need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/doc/bitcoin_logo_doxygen.png b/doc/bitcoin_logo_doxygen.png deleted file mode 100644 index 7d7afda81cc62577b3721cf83ecd3f673a114aea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5445 zcmV-L6}sw)P)UWAqqnT-(cQ+qP}nwryK`ZDCfJ9os$AR&`b0N&2K;UVq;_Y3}|vDJA)H zkdu?vmH*zKDoP0&fMA^<#2-aC0GpKvDoVt^{YU;wqy#jCYyK=x;kq?uQNCOCxOCz& zHDWkaQ3>>zv>ZE}ps9(Nome%H3ODs6BMRIGq!E@Nj3xbllT&q7(b7&+n?_IdTp%j zg`dM6@J@megtt?aDk&t0B>%VM2z07Jr#ec@^Xkdf3pQ?a?OfzhH}V+j3{xkix%!ve zE0G4^P%h0tDB*OCh3)3=+Y;ZN`O?UD@F<89jRP3Tv{2dqHaUVY06HsQKB;PlMRUEU zdku9iNT`yr=KWHF{|L!tlWTVTZAuA$gNo6sLvqIuK2F z`K_N$cxLGCAKMe{@L~WE1|*OqMf}_32ujNIn56LK6RUUJVIA*%x<-nidu~RA!aFJw zApnXcfIZ^3Kt2w<&t6x#h>;H$7%O-sdl#7TiVBT^$|fH9I&jNnZ;gEpHa?6bqnseB z>Aypc5Fkc@*e>gPYwkI?;=HLo;}jSR3JOI;5Tee9l$9D~WQIak?2X?79Sx@&h$NxRsH)9kHAz~I4hm$45QQC%6zhC&;=)E7Uh%SY8{D9D81l37Z5hZrj zo@MKvx~S+5PAvP7D;InXARKIN6#^v(zmL~YT8?Tr4<`HJ(*Z#5RG%y0b{U4EYDy%f zq#pcYZ0S*tb$xpI8-pKzvo^X`*EGVur3h$)Kzn@hrdPN&1AD({xAnc7LR&sSA;1Kv zxx&&XA;uTteKyXk1!A`rd9?Xibs;K>g_9C0NKHc{Ov`MT5y#=Sh7Lv{DVti~wnSRs zT~gxJ7UdA*Qc+X@&a445{l>4so|``y z`tzr@SXb0iQo61wTmqV|SX4>A`jdY-+R51bxka;tB*vol7!YegsdjHQqiCvw5|@Ay zR0(6p`khhf+UW74t4@Xy)xmdVfIJkII+^6SI>PL`KR>VTz{XPJ7*Kyc`w}rEMR-Y| zEe(iV_Im#x?IX!9Md@cYm7G7P(6{gAWz)8pUf4Jmwuazd7b6A;*ZaI15ST*CcC2OH zu{C&qY(4LOZ) zV#bBLl+508n)`NU*0N)ei4j(ZQUeKgj#?2Q#%yX3B@p?xIkX1w9d?$`R3&OV%J_^* zx0$lZP~4)0NlURmXqxyHCF;LozlO!E4^GVC@iXfgT{Bt%6Cx(@+q;d0<))P;$+>S9V+uFSX$WhXE-;j<^kCBrK|ab5Z??TTFG`&Daob@;P1+Ku{g2%InM< zI)edgY%F4TwG768y8f;1588&}eYg&#azZ8p?ZeCJgtO-pk$mr>4fdZ~mv?AwiMfSK zSJZUc&XN?wh$0cpkfzkO>BC=+KY9LZBhN#7eKe!y@$4Rq5!-62yKcQ&^H{E-Vi8uc zWMlwDk%{qp)X-FQN`%&OUD4&Ls=>T6C!%sEg8lJQQL$vBfxo>sDck|V!Ku(*5!`eG zG)|6-2XNa#<-53aGMy7c!xi?%)e%9n4fB$#txZ+xQ08WJ!(-}GG?kQNC+yDw6QZZ> zGNs`8vo>BArKU+B4&_o!ez|g@?dEs7Ki~Vd<##>)<>1S4OG%O(f_!Mg51^wfE6}Sh z*|mH-B||PBVDJ&r47q|SW#%GXBZXYgRVng7N5Y|MTykQa6JP^Su;bRDcx*J3GQ{GF zAV)85n79A7b?+x$+q13b@tvQ2=B!N)C@(PUVXl0rsub;YU|=G(`m`roo`39%!KV|J z665XTc%-EvJIQ%2&9m)H@5XRZh2&hSaQ}}VUAaNNn`{7ezW8QU5z6d;k|a4Ka)N9) zNt4Zkv5-s(OQX>1+DOwhpQ`D4b*Xp35epk{>w0|W&px_xo73jh=1*l4jFJv8g3v|p zg)g+d^jmxQOG;ITOAq@ds7+Y%Wxl4=Y&dv}!r8nXB*&mlEjMPmb#SoIb_L^hbXjNEFWDCbs14=bQjgo11;hv?8f7!@KzlCJ@NU0hBOHdoV#K`Ba& z{&lY`&6XqxS#qc@fIuW2`C`S`ptR?*0pzIdr_^}d=5&e?hgdTmqH>~}%`Dyf=*5lO zGV@`xj^9OrPGBr#wOO_j$r2-3WOpAxj=Bw%Os_EOJq9Ud83Imjr**s~kRq6kyDJ1i zy;gDv38*<10d6?3w$1zQI7#P;p8$z3HP|VuFR|{n5z;Z zyqyY2JCsjSjH<-WozSfGkRWqt(|{ZhEED8(*lHAdOwvG6$btkfQTQ}x&z1`UNT#Xv zM|-Fb7v-3wmZY-8Tjny&DnSYe@-hoeQ&x0`0uH5ed??aryS&^rhXe!^4 z=cX=ojgW6w4zGOmyWSScC515}l00#T`YDRaT_gsCD(={ER5)Jt0dQgIL}s@xPEJ#a z8~V-1K}!>ZQo{zs1CDGqA*=f|oUr4+v`q9OIWb6wVXJdKdgri3)B1PXq;{w3GVhE$ zQ!myuV%oOtwDboDu6=RY*S%x0PTb5Uuv-nFAG^4ICxW_|I|d;^&J_k!;MNSVIZu|H zsVSxoFF4unB$6l@l%m96R$IawZt4j3V8|7fcgIN3dg-f`y&!&uJU3+fZvoBlF1i!ZgxP< zZ4gt0UnF5sM^Z+a9p1`qC`WSeFKtu%sn5Gx7%@Z|KwO4qbUbt5nSC!F_TVQs?RM~@ zjcTjW9z#fE49WWOI@1OrEdEb4o>t_lSiX)?WF+4ST%Q^YSr|zkSWFN5b#B4h$+ zv7}9Je64w4n@hgFt!p^?19nFKnaPd=5zD6BOLKC;m=jA{bc9o%jEFMHGn#S2FMiXz zMzX7vaOG$2IcG7tGMe3!QJb*3+fa%RT{!KE53b$eGor z;!ObRjGFvKNQzKu12Hf~P7to)PbE~{cHN3YF4%uvwq4<2lOU%OCHnsF!+%ahtX}pm zx;%iSO;SmKz(_D148&~i&=@&qMPD)iXJzetxyUv`C5l;M{COa1rJA}zBV8l$@$pD1 zwq)t(PnfowkerDMaKV;lYwB=vQko!**EVrLCn2IJm{yrLN8vUohhDs`NZN5G-~;55 zLo7S#85`@Ju>8ZpG*8s(Ome?E@Z0Cijg(#+(e!2vX!(scT>F{PpvdfwuZG zceJL|6aTq2(1xzv4~UE0;WdY?HyhT_a*!Bb?=g=i&37hkZl@i^A5KtVbJ)9s8j#?N zFp@%&SW?+E2%C-7{fR+HcW|%E$uX9lV^+sjDaY?|sbyTm0E(rUF%^il568zJTr$wa zCTZ4WBY=U+yJ+;r@t9qjYLKOgNPv{ z7L!6QbNw?uefE~uSD*at@}Um~{gD9*_LkY?I0^%`ZRO|Y(X}Vu|MM$LI|3a!Su?`i z?G&G<%G5})INF*-f_&O~{nqHW&Cy;Y7t=)&^ULOVPw%+ZR8gR92D7c9sL|dWTt+F2 zX|$PDZZ9m9W;mW!{a_K25fB6guzYU(isx5+5A{|+IjC3Fx{XD?vI19LB%ZdLIwr=G zmNSl%H7KdIBOKCQ$IRYV(`X@ISg3#_k>n*wfnhdvN4vYnt$t2UQp+?T_3V$~C3CA? zd*r)mU3QiT07+Uf+#3&S*!r6N8@KBATdh6*zVt66rik%2$T4 z9!aI?a8rB0gt{*5N{UtjSSE3z440vnZ91)RFP$hwGBK=UsxLznCOQ1_&%sqvJDA!- za!-60T-GsW{RrPV>{Bi=JU0{WJ7sZCN2d79SqtVC9eTpz>f6uTqv3%Y51D=)2E+wy zmw}VUH<~z;!+;(@XHGoXjcOf0Vgwya!RJ?PdU$!hHlGpTLy~L`$HPs?aVY(zJ=zW@ zM9ruLVc{)>rKZ@8GhQ5d=F@X)7kf-nE*g?0C{A1)whm*Crog3E2BLHZ9w{+>Om{!B z@M2xlD*F8K)u%qT>Z3n9f&u(>f>1e)1N#@!M0kI^Ve=C=XvjZP*OWZ!{53I)5YCRP zWCXTa7rZj~4XX7x1`?Kzk`rz>{%dEV{q;X0j~%;h;bmz`ar`Jf(IAcwcXd3r{Bos# z4W70{j$d3er^u`A<2Lo#rTGO>ScKs`fD^NK+oZy~^G4;hKdzmyUj1P(F4>p~3Ei5* z=T&dA<&44u;QNg=LfuR(gxa#bL6Oxc3QG;S{iBhud;C@>2H*kI7F&>`k{U%%dUp8T zEvCA+Tc_HbZ{rz6cGJq~s2N?Syw3CWFMdDNi_wL#Xx$PvFdtJJHmjW@F&Bnb(R+`Z zdk(CRC!f4iz46SM8?XkXpur)8QkAa)PzMqeZH#dK)MkW`m`zz8?d#Q{_S-)m{h6sf zk_(C0mXnjEhaw%{`~Lphf4#h6R&gGwVhxI48aR%FX$uS}1|VhShb@Z1updiBRv4N52XFGTmp~f5QCYv+~?Zkvt28^{Hl#h--?pf|pL8u|w~8s@`R2 z$+A3kCL4qeI(`2qeT)sh!vSejs z8G746^pbLNNg;pdcPDNPWNU9buzZgb<`tir=hg~f-uUscblSpyilJ#5U+NPUcqvWQ zG?l0^i&_`I*!9k5D<_&dMv^U`U%tWNaAdr%6q8Hj6f7mO!Yk5@)-Y9spgnQjyTeN! z_}u?JE+?HRHL;Y~|7d%wB0&!ltT}aI(fn)o_FY( z;QwXG;i`ay0Nj7XQ?>=aQ~CbNw}!tJzhl92RK$?~&M$~^3AzA6rV)S6N;+sC1zOROT|by9qWhGz>2;^-}2sg-;b@ao?koTT_~Li zBs3xAXOd!({%`+MmPk@G0B)3I0irn1MapJXx+-8_Sn74Fg}wr Date: Sun, 8 Oct 2017 00:11:53 +0200 Subject: [PATCH 027/166] Reorder beacon advertising procedure and better error reporting. --- src/rpcblockchain.cpp | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index fe8e2f8cd3..8b6cfb95f9 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -1007,36 +1007,44 @@ bool AdvertiseBeacon(std::string &sOutPrivKey, std::string &sOutPubKey, std::str std::string sName = GlobalCPUMiningCPID.cpid; try { - // Store the key - sMessage = AddContract(sType,sName,sBase); + // Backup config with old keys like a normal backup - std::string sBeaconBackupOldConfigFilename = GetBackupFilename("gridcoinresearch.conf"); - boost::filesystem::path sBeaconBackupOldConfigTarget = GetDataDir() / "walletbackups" / sBeaconBackupOldConfigFilename; - BackupConfigFile(sBeaconBackupOldConfigTarget.string().c_str()); - StoreBeaconKeys(GlobalCPUMiningCPID.cpid, sOutPubKey, sOutPrivKey); + if(!BackupConfigFile(GetBackupFilename("gridcoinresearch.conf"))) + { + sError = "Failed to backup old configuration file. Beacon not sent."; + return false; + } + // Backup config with new keys with beacon suffix - std::string sBeaconBackupNewConfigFilename = GetBackupFilename("gridcoinresearch.conf", "beacon"); - boost::filesystem::path sBeaconBackupNewConfigTarget = GetDataDir() / "walletbackups" / sBeaconBackupNewConfigFilename; - BackupConfigFile(sBeaconBackupNewConfigTarget.string().c_str()); + StoreBeaconKeys(GlobalCPUMiningCPID.cpid, sOutPubKey, sOutPrivKey); + if(!BackupConfigFile(GetBackupFilename("gridcoinresearch.conf", "beacon"))) + { + sError = "Failed to backup new configuration file. Beacon not sent. And your config file is probably corrupted now."; + return false; + } + + // This prevents repeated beacons + nLastBeaconAdvertised = nBestHeight; + // Send the beacon transaction + sMessage = AddContract(sType,sName,sBase); // Activate Beacon Keys in memory. This process is not automatic and has caused users who have a new keys while old ones exist in memory to perform a restart of wallet. ActivateBeaconKeys(GlobalCPUMiningCPID.cpid, sOutPubKey, sOutPrivKey); - // Since everything was successful add LastAdvertisedBeacon block height to memory. - nLastBeaconAdvertised = nBestHeight; + return true; } catch(Object& objError) { - sError = "Error: Unable to send beacon::Wallet Locked::Please enter the wallet passphrase with walletpassphrase first."; + sError = "Error: Unable to send beacon::"+json_spirit::write_string(json_spirit::Value(objError),true); return false; } catch (std::exception &e) { - sError = "Error: Unable to send beacon::Wallet Locked::Please enter the wallet passphrase with walletpassphrase first."; + sError = "Error: Unable to send beacon;:"+std::string(e.what()); return false; } catch(...) { - sError = "Error: Unable to send beacon::Wallet Locked::Please enter the wallet passphrase with walletpassphrase first."; + sError = "Error: Unable to send beacon::Unknown Exception."; return false; } } From e0d929001d04d30a1bc13c3a19641ad255001b8e Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 8 Oct 2017 16:53:47 +0200 Subject: [PATCH 028/166] Possible fix for size_t discrepancies in Linux vs OSX. --- src/json/json_spirit_value.h | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h index c39ef24b96..fd747633c7 100644 --- a/src/json/json_spirit_value.h +++ b/src/json/json_spirit_value.h @@ -46,12 +46,19 @@ namespace json_spirit Value_impl( bool value ); Value_impl( int value ); Value_impl( unsigned int value ); - Value_impl( int64_t value ); - Value_impl( uint64_t value ); + Value_impl( int64_t value ); + Value_impl( uint64_t value ); Value_impl( double value ); - + +#ifdef __APPLE__ + // Workaround for size_t ambiguously converting to int64/uint64 on + // OSX while being redefined as uint64_t on Linux. There must be + // a better way to do this. + Value_impl( size_t value ); +#endif + Value_impl( const Value_impl& other ); - + bool operator==( const Value_impl& lhs ) const; Value_impl& operator=( const Value_impl& lhs ); @@ -279,6 +286,16 @@ namespace json_spirit , is_uint64_( false ) { } + +#ifdef __APPLE__ + template< class Config > + Value_impl< Config >::Value_impl( size_t value ) + : type_( int_type ) + , v_( value ) + , is_uint64_( false ) + { + } +#endif template< class Config > Value_impl< Config >::Value_impl( uint64_t value ) From 1e0200f2dca14159a591889729a772a810edcaa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Mon, 9 Oct 2017 07:34:06 +0200 Subject: [PATCH 029/166] Requested improvements to the PR. --- src/rpcblockchain.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 8b6cfb95f9..e529173a2f 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -1019,14 +1019,14 @@ bool AdvertiseBeacon(std::string &sOutPrivKey, std::string &sOutPubKey, std::str StoreBeaconKeys(GlobalCPUMiningCPID.cpid, sOutPubKey, sOutPrivKey); if(!BackupConfigFile(GetBackupFilename("gridcoinresearch.conf", "beacon"))) { - sError = "Failed to backup new configuration file. Beacon not sent. And your config file is probably corrupted now."; + sError = "Failed to back up configuration file. Beacon not sent, please manually roll back to previous configuration."; return false; } - // This prevents repeated beacons - nLastBeaconAdvertised = nBestHeight; // Send the beacon transaction sMessage = AddContract(sType,sName,sBase); + // This prevents repeated beacons + nLastBeaconAdvertised = nBestHeight; // Activate Beacon Keys in memory. This process is not automatic and has caused users who have a new keys while old ones exist in memory to perform a restart of wallet. ActivateBeaconKeys(GlobalCPUMiningCPID.cpid, sOutPubKey, sOutPrivKey); @@ -1042,11 +1042,6 @@ bool AdvertiseBeacon(std::string &sOutPrivKey, std::string &sOutPubKey, std::str sError = "Error: Unable to send beacon;:"+std::string(e.what()); return false; } - catch(...) - { - sError = "Error: Unable to send beacon::Unknown Exception."; - return false; - } } } From 8853b60f6d75fecdd3b951c75f241930a0cd37c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1?= Date: Mon, 9 Oct 2017 08:31:48 +0200 Subject: [PATCH 030/166] Reorder beacon advertising procedure and better error reporting. (#684) Reorder beacon advertising procedure and better error reporting. --- src/rpcblockchain.cpp | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 796a6fed1d..d33275e208 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -1007,36 +1007,39 @@ bool AdvertiseBeacon(std::string &sOutPrivKey, std::string &sOutPubKey, std::str std::string sName = GlobalCPUMiningCPID.cpid; try { - // Store the key - sMessage = AddContract(sType,sName,sBase); + // Backup config with old keys like a normal backup - std::string sBeaconBackupOldConfigFilename = GetBackupFilename("gridcoinresearch.conf"); - boost::filesystem::path sBeaconBackupOldConfigTarget = GetDataDir() / "walletbackups" / sBeaconBackupOldConfigFilename; - BackupConfigFile(sBeaconBackupOldConfigTarget.string().c_str()); - StoreBeaconKeys(GlobalCPUMiningCPID.cpid, sOutPubKey, sOutPrivKey); + if(!BackupConfigFile(GetBackupFilename("gridcoinresearch.conf"))) + { + sError = "Failed to backup old configuration file. Beacon not sent."; + return false; + } + // Backup config with new keys with beacon suffix - std::string sBeaconBackupNewConfigFilename = GetBackupFilename("gridcoinresearch.conf", "beacon"); - boost::filesystem::path sBeaconBackupNewConfigTarget = GetDataDir() / "walletbackups" / sBeaconBackupNewConfigFilename; - BackupConfigFile(sBeaconBackupNewConfigTarget.string().c_str()); + StoreBeaconKeys(GlobalCPUMiningCPID.cpid, sOutPubKey, sOutPrivKey); + if(!BackupConfigFile(GetBackupFilename("gridcoinresearch.conf", "beacon"))) + { + sError = "Failed to back up configuration file. Beacon not sent, please manually roll back to previous configuration."; + return false; + } + + // Send the beacon transaction + sMessage = AddContract(sType,sName,sBase); + // This prevents repeated beacons + nLastBeaconAdvertised = nBestHeight; // Activate Beacon Keys in memory. This process is not automatic and has caused users who have a new keys while old ones exist in memory to perform a restart of wallet. ActivateBeaconKeys(GlobalCPUMiningCPID.cpid, sOutPubKey, sOutPrivKey); - // Since everything was successful add LastAdvertisedBeacon block height to memory. - nLastBeaconAdvertised = nBestHeight; + return true; } catch(Object& objError) { - sError = "Error: Unable to send beacon::Wallet Locked::Please enter the wallet passphrase with walletpassphrase first."; + sError = "Error: Unable to send beacon::"+json_spirit::write_string(json_spirit::Value(objError),true); return false; } catch (std::exception &e) { - sError = "Error: Unable to send beacon::Wallet Locked::Please enter the wallet passphrase with walletpassphrase first."; - return false; - } - catch(...) - { - sError = "Error: Unable to send beacon::Wallet Locked::Please enter the wallet passphrase with walletpassphrase first."; + sError = "Error: Unable to send beacon;:"+std::string(e.what()); return false; } } From 1e2472f3370185db4d43e05a12bb1ec8aa3f2d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Mon, 9 Oct 2017 07:36:33 +0200 Subject: [PATCH 031/166] Attempt to fix again the stake modifier. --- src/kernel.cpp | 24 ++++++++++-------------- src/main.cpp | 6 +++--- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index 09335181af..9645b47f06 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -144,6 +144,15 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod if (nModifierTime / nModifierInterval >= pindexPrev->GetBlockTime() / nModifierInterval) return true; + const uint256 ModifGlitch_hash("439b96fd59c3d585a6b93ee63b6e1d78361d7eb9b299657dee6a2c5400ccba29"); + const uint64_t ModifGlitch_correct=0xdf209a3032807577; + if(pindexPrev->GetBlockHash()==ModifGlitch_hash) + { + nStakeModifier = ModifGlitch_correct; + fGeneratedStakeModifier = true; + return true; + } + // Sort candidate blocks by timestamp vector > vSortedByTimestamp; vSortedByTimestamp.reserve(64 * nModifierInterval / GetTargetSpacing(pindexPrev->nHeight)); @@ -745,7 +754,7 @@ bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned printf("-"); //if (pindexPrev) nGrandfatherHeight = pindexPrev->nHeight; - if (pindexPrev->nHeight > nGrandfather) + if (pindexPrev->nHeight > nGrandfather || pindexPrev->nHeight >= 999000) { if (!CheckStakeKernelHash(pindexPrev, nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, txPrev, txin.prevout, tx.nTime, hashProofOfStake, targetProofOfStake, hashBoinc, fDebug, checking_local, por_nonce)) @@ -847,25 +856,12 @@ bool FindStakeModifierRev(uint64_t& nStakeModifier,CBlockIndex* pindexPrev) { nStakeModifier = 0; const CBlockIndex* pindex = pindexPrev; - const uint256 ModifGlitch_hash("12bcc37789ef00809d1287f4af3c46106181e7c60654c7d3f0677aefa8a78774"); - const uint64_t ModifGlitch_correct=0xdf209a3032807577; while (1) { if(!pindex) return error("FindStakeModifierRev: no previous block from %d",pindexPrev->nHeight); - if (pindex->GetBlockHash()==ModifGlitch_hash) - { - if(pindex->nStakeModifier!=ModifGlitch_correct) - printf("WARNING: Correcting Stake Modifier Glitch, wrong= %016" - PRIx64 ", correct %016" PRIx64 "\n", - pindex->nStakeModifier, ModifGlitch_correct); - - nStakeModifier = ModifGlitch_correct; - return true; - } - if (pindex->GeneratedStakeModifier()) { nStakeModifier = pindex->nStakeModifier; diff --git a/src/main.cpp b/src/main.cpp index c90efb2ddd..0b41f8b6cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4058,7 +4058,7 @@ bool CBlock::AcceptBlock(bool generated_by_me) if (IsProofOfWork() && nHeight > LAST_POW_BLOCK) return DoS(100, error("AcceptBlock() : reject proof-of-work at height %d", nHeight)); - if (nHeight > nGrandfather) + if (nHeight > nGrandfather || nHeight >= 999000) { // Check coinbase timestamp if (GetBlockTime() > FutureDrift((int64_t)vtx[0].nTime, nHeight)) @@ -4086,12 +4086,12 @@ bool CBlock::AcceptBlock(bool generated_by_me) uint256 hashProof; // Verify hash target and signature of coinstake tx - if (nHeight > nGrandfather && nVersion <= 7) + if ((nHeight > nGrandfather || nHeight >= 999000) && nVersion <= 7) { if (IsProofOfStake()) { uint256 targetProofOfStake; - if (!CheckProofOfStake(pindexPrev, vtx[1], nBits, hashProof, targetProofOfStake, vtx[0].hashBoinc, generated_by_me, nNonce) && IsLockTimeWithinMinutes(GetBlockTime(),600)) + if (!CheckProofOfStake(pindexPrev, vtx[1], nBits, hashProof, targetProofOfStake, vtx[0].hashBoinc, generated_by_me, nNonce) && (IsLockTimeWithinMinutes(GetBlockTime(),600) || nHeight >= 999000)) { return error("WARNING: AcceptBlock(): check proof-of-stake failed for block %s, nonce %f \n", hash.ToString().c_str(),(double)nNonce); } From e246324659d6b20d153535795d90b0b83487434c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Tue, 10 Oct 2017 15:41:29 +0200 Subject: [PATCH 032/166] Report error for invalid cpid when advertising beacon. --- src/rpcblockchain.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index e529173a2f..203a55ba7c 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -979,7 +979,11 @@ bool AdvertiseBeacon(std::string &sOutPrivKey, std::string &sOutPubKey, std::str GlobalCPUMiningCPID.cpidv2 = ComputeCPIDv2(GlobalCPUMiningCPID.email, GlobalCPUMiningCPID.boincruntimepublickey, hashRand); bool IsCPIDValid2 = CPID_IsCPIDValid(GlobalCPUMiningCPID.cpid,GlobalCPUMiningCPID.cpidv2, hashRand); - if (!IsCPIDValid2) return "Invalid CPID"; + if (!IsCPIDValid2) + { + sError="Invalid CPID"; + return false; + } double nBalance = GetTotalBalance(); if (nBalance < 1.01) From 5242805e5b50669503b04df3e721a9516ceb4e92 Mon Sep 17 00:00:00 2001 From: Nick Boone Date: Sat, 14 Oct 2017 06:05:41 +0100 Subject: [PATCH 033/166] C++ Diagnostics Page (#631) Qt Diagnostistic Implementation. --- gridcoinresearch.pro | 7 +- src/qt/bitcoingui.cpp | 14 +- src/qt/bitcoingui.h | 2 + src/qt/diagnosticsdialog.cpp | 357 +++++++++++++++++++++++++ src/qt/diagnosticsdialog.h | 51 ++++ src/qt/forms/diagnosticsdialog.ui | 428 ++++++++++++++++++++++++++++++ 6 files changed, 851 insertions(+), 8 deletions(-) create mode 100644 src/qt/diagnosticsdialog.cpp create mode 100644 src/qt/diagnosticsdialog.h create mode 100644 src/qt/forms/diagnosticsdialog.ui diff --git a/gridcoinresearch.pro b/gridcoinresearch.pro index 82702155e2..5be69aa413 100755 --- a/gridcoinresearch.pro +++ b/gridcoinresearch.pro @@ -134,7 +134,8 @@ contains(NO_UPGRADE, 1) { INCLUDEPATH += src/leveldb/include src/leveldb/helpers LIBS += $$PWD/src/leveldb/libleveldb.a $$PWD/src/leveldb/libmemenv.a -SOURCES += src/txdb-leveldb.cpp +SOURCES += src/txdb-leveldb.cpp \ + src/qt/diagnosticsdialog.cpp !win32 { # we use QMAKE_CXXFLAGS_RELEASE even without RELEASE=1 because we use RELEASE to indicate linking preferences not -O preferences genleveldb.commands = cd $$PWD/src/leveldb && CC=\"$$QMAKE_CC\" CXX=\"$$QMAKE_CXX\" $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" libleveldb.a libmemenv.a @@ -271,6 +272,7 @@ HEADERS += src/qt/bitcoingui.h \ src/cpid.h \ src/upgrader.h \ src/boinc.h \ + src/qt/diagnosticsdialog.h \ src/backup.h \ src/appcache.h @@ -374,7 +376,8 @@ FORMS += \ src/qt/forms/sendcoinsentry.ui \ src/qt/forms/askpassphrasedialog.ui \ src/qt/forms/rpcconsole.ui \ - src/qt/forms/optionsdialog.ui + src/qt/forms/optionsdialog.ui \ + src/qt/forms/diagnosticsdialog.ui contains(USE_QRCODE, 1) { HEADERS += src/qt/qrcodedialog.h diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 5edbcea5bc..7e98a98d3c 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -24,6 +24,7 @@ #include "transactiontablemodel.h" #include "addressbookpage.h" +#include "diagnosticsdialog.h" #include "upgradedialog.h" #include "upgrader.h" #include "sendcoinsdialog.h" @@ -241,6 +242,8 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): connect(downloadAction, SIGNAL(triggered()), upgrader, SLOT(show())); connect(downloadAction, SIGNAL(triggered()), upgrader, SLOT(blocks())); + diagnosticsDialog = new DiagnosticsDialog(this); + // Clicking on "Verify Message" in the address book sends you to the verify message tab connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString))); @@ -767,6 +770,8 @@ void BitcoinGUI::createMenuBar() QMenu *help = appMenuBar->addMenu(tr("&Help")); help->addAction(openRPCConsoleAction); help->addSeparator(); + help->addAction(diagnosticsAction); + help->addSeparator(); help->addAction(aboutAction); #ifdef WIN32 help->addSeparator(); @@ -1360,12 +1365,9 @@ void BitcoinGUI::configClicked() void BitcoinGUI::diagnosticsClicked() { -#ifdef WIN32 - if (!bGlobalcomInitialized) return; - qtSetSessionInfo(DefaultWalletAddress(), GlobalCPUMiningCPID.cpid, GlobalCPUMiningCPID.Magnitude); - bool result = PushGridcoinDiagnostics(); - globalcom->dynamicCall("ShowDiagnostics()"); -#endif + diagnosticsDialog->show(); + diagnosticsDialog->raise(); + diagnosticsDialog->activateWindow(); } void BitcoinGUI::foundationClicked() diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index bebe958463..8b9d66c594 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -27,6 +27,7 @@ class SignVerifyMessageDialog; class Notificator; class RPCConsole; class UpgradeDialog; +class DiagnosticsDialog; QT_BEGIN_NAMESPACE class QLabel; @@ -136,6 +137,7 @@ class BitcoinGUI : public QMainWindow TransactionView *transactionView; RPCConsole *rpcConsole; UpgradeDialog *upgrader; + DiagnosticsDialog *diagnosticsDialog; QMovie *syncIconMovie; diff --git a/src/qt/diagnosticsdialog.cpp b/src/qt/diagnosticsdialog.cpp new file mode 100644 index 0000000000..e5c2af01b3 --- /dev/null +++ b/src/qt/diagnosticsdialog.cpp @@ -0,0 +1,357 @@ +#include + +#include +#include "main.h" +#include "util.h" +#include "boinc.h" +#include +#include +#include + +#include "diagnosticsdialog.h" +#include "ui_diagnosticsdialog.h" + +std::string GetListOf(std::string datatype); +double PreviousBlockAge(); + +DiagnosticsDialog::DiagnosticsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::DiagnosticsDialog) +{ + ui->setupUi(this); + + networkManager = new QNetworkAccessManager(this); + connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(getGithubVersionFinished(QNetworkReply *))); +} + +DiagnosticsDialog::~DiagnosticsDialog() +{ + delete ui; +} + +int DiagnosticsDialog::VarifyBoincPath() { + boost::filesystem::path boincPath = (boost::filesystem::path) GetBoincDataDir(); + if(boincPath.empty()) + boincPath = (boost::filesystem::path) GetArgument("boincdatadir", ""); + + boincPath = boincPath / "client_state.xml"; + + if(boost::filesystem::exists(boincPath)) + return 1; + else + return 0; +} + +int DiagnosticsDialog::FindCPID() { + std::string cpid = GetArgument("cpid", ""); + + if(cpid.length() != 0) + return 1; + else + return 0; +} + +int DiagnosticsDialog::VarifyIsCPIDValid() { + boost::filesystem::path clientStatePath = (boost::filesystem::path) GetBoincDataDir(); + if(!clientStatePath.empty()) + clientStatePath = clientStatePath / "client_state.xml"; + else + clientStatePath = (boost::filesystem::path) GetArgument("boincdatadir", "") / "client_state.xml"; + + if(clientStatePath.empty()) + return 0; + + std::ifstream clientStateStream; + std::string clientState; + + clientStateStream.open(clientStatePath.string()); + clientState.assign((std::istreambuf_iterator(clientStateStream)), std::istreambuf_iterator()); + clientStateStream.close(); + + size_t pos = 0; + std::string cpid; + if((pos = clientState.find("")) != std::string::npos) { + cpid = clientState.substr(pos + 15, clientState.length()); + pos = cpid.find(""); + cpid.erase(pos, cpid.length()); + } + + if(GetArgument("cpid", "") == cpid) + return 1; + else + return 0; +} + +int DiagnosticsDialog::VerifyCPIDIsInNeuralNetwork() { + std::string beacons = GetListOf("beacon"); + boost::algorithm::to_lower(beacons); + + if(beacons.length() < 100) + return -1; + + std::string cpid = GetArgument("cpid", ""); + if(cpid != "" && beacons.find(cpid) != std::string::npos) + return 1; + else + return 0; +} + +int DiagnosticsDialog::VarifyWalletIsSynced() { + std::string walletAgeString = ToString(PreviousBlockAge()); + long int walletAge = std::stoi(walletAgeString,nullptr,10); + + if(walletAgeString.length() == 0) + return -1; + if(walletAge < (60 * 60)) + return 1; + else + return 0; + +} + +int DiagnosticsDialog::VarifyCPIDHasRAC() { + boost::filesystem::path clientStatePath = (boost::filesystem::path) GetBoincDataDir(); + if(!clientStatePath.empty()) + clientStatePath = clientStatePath / "client_state.xml"; + else + clientStatePath = (boost::filesystem::path) GetArgument("boincdatadir", "") / "client_state.xml"; + + if(clientStatePath.empty()) + return 0; + + std::ifstream clientStateStream; + std::string clientState; + std::vector racStrings; + std::vector racValues; + + clientStateStream.open(clientStatePath.string()); + clientState.assign((std::istreambuf_iterator(clientStateStream)), std::istreambuf_iterator()); + clientStateStream.close(); + + if(clientState.length() > 0) { + size_t pos = 0; + std::string delim = ""; + std::string line; + while ((pos = clientState.find(delim)) != std::string::npos) { + line = clientState.substr(0, pos); + clientState.erase(0, pos + delim.length()); + pos = line.find(""); + racStrings.push_back(line.substr(pos + 20, line.length())); + } + for(std::string racString : racStrings) { + racValues.push_back(std::stod(racString, nullptr)); + } + return (int) std::accumulate(racValues.begin(), racValues.end(), 0); + } else + return 0; + +} + +int DiagnosticsDialog::VarifyAddNode() { + long int peersLength = boost::filesystem::file_size(GetDataDir(true) / "peers.dat"); + std::string addNode = GetArgument("addnode", ""); + + if(addNode.length() == 0 && peersLength > 100) + return 2; + if(addNode.length() > 4 && peersLength == 0) + return 3; + if(peersLength > 100) + return 1; + if(peersLength == 0 && addNode == "") + return -1; + return 0; + +} + +void DiagnosticsDialog::VarifyClock() { + QHostInfo info = QHostInfo::fromName("pool.ntp.org"); + udpSocket = new QUdpSocket(this); + + connect(udpSocket, SIGNAL(readyRead()), this, SLOT(clkFinished())); + + udpSocket->bind(QHostAddress::LocalHost, 123); + + QByteArray sendBuffer = QByteArray(47, 0); + sendBuffer.insert(0, 35); + + connect(udpSocket, SIGNAL(readyRead()), this, SLOT(clkFinished())); + udpSocket->writeDatagram(sendBuffer, info.addresses().first(), 123); +} + + + +void DiagnosticsDialog::VarifyTCPPort() { + tcpSocket = new QTcpSocket(this); + + connect(tcpSocket, SIGNAL(connected()), this, SLOT(TCPFinished())); + connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(TCPFailed(QAbstractSocket::SocketError))); + + tcpSocket->connectToHost("london.grcnode.co.uk", 32749); + +} + +void DiagnosticsDialog::on_testBtn_clicked() { + int result = 0; + //boinc path + ui->boincPathResultLbl->setText("Testing..."); + this->repaint(); + result = DiagnosticsDialog::VarifyBoincPath(); + if(result == 1) + ui->boincPathResultLbl->setText("Passed"); + else + ui->boincPathResultLbl->setText("Failed"); + //find cpid + ui->findCPIDReaultLbl->setText("Testing..."); + this->repaint(); + result = DiagnosticsDialog::FindCPID(); + if(result == 1) + ui->findCPIDReaultLbl->setText(QString::fromStdString("Passed CPID: " + GetArgument("cpid", ""))); + else + ui->findCPIDReaultLbl->setText("Failed (Is CPID in gridcoinresearch.conf?)"); + //cpid valid + ui->varifyCPIDValidResultLbl->setText("Testing..."); + this->repaint(); + result = DiagnosticsDialog::VarifyIsCPIDValid(); + if(result == 1) + ui->varifyCPIDValidResultLbl->setText("Passed"); + else + ui->varifyCPIDValidResultLbl->setText("Failed (BOINC CPID and gridcoinresearch.conf CPID do not match)"); + //cpid has rac + ui->varifyCPIDHasRACResultLbl->setText("Testing..."); + this->repaint(); + result = DiagnosticsDialog::VarifyCPIDHasRAC(); + if(result > 0) + ui->varifyCPIDHasRACResultLbl->setText(QString::fromStdString("Passed RAC: " + std::to_string(result))); + else + ui->varifyCPIDHasRACResultLbl->setText("Failed"); + //cpid is in nn + ui->varifyCPIDIsInNNResultLbl->setText("Testing..."); + this->repaint(); + result = DiagnosticsDialog::VerifyCPIDIsInNeuralNetwork(); + if(result == 1) + ui->varifyCPIDIsInNNResultLbl->setText("Passed"); + else if (result == -1) + ui->varifyCPIDIsInNNResultLbl->setText("Beacon data empty, sync wallet"); + else + ui->varifyCPIDIsInNNResultLbl->setText("Failed"); + //wallet synced + ui->varifyWalletIsSyncedResultLbl->setText("Testing..."); + this->repaint(); + result = DiagnosticsDialog::VarifyWalletIsSynced(); + if(result == 1) + ui->varifyWalletIsSyncedResultLbl->setText("Passed"); + else if (result == -1) + ui->varifyWalletIsSyncedResultLbl->setText("Sync data empty"); + else + ui->varifyWalletIsSyncedResultLbl->setText("Failed"); + //clock + ui->varifyClkResultLbl->setText("Testing..."); + this->repaint(); + DiagnosticsDialog::VarifyClock(); + //addnode + ui->varifyAddnodeResultLbl->setText("Testing..."); + this->repaint(); + result = DiagnosticsDialog::VarifyAddNode(); + if(result == 1) + ui->varifyAddnodeResultLbl->setText("Passed"); + else if(result == 2) + ui->varifyAddnodeResultLbl->setText("Passed (Addnode does not exist but peers are synced)"); + else if(result == 3) + ui->varifyAddnodeResultLbl->setText("Passed (Addnode exists but peers not synced)"); + else if(result == -1) + ui->varifyAddnodeResultLbl->setText("Failed (Please add addnode=node.gridcoin.us in conf file)"); + else + ui->varifyAddnodeResultLbl->setText("Failed"); + //tcp port + ui->varifyTCPPortResultLbl->setText("Testing..."); + this->repaint(); + DiagnosticsDialog::VarifyTCPPort(); + //client version + ui->checkClientVersionResultLbl->setText("Testing..."); + networkManager->get(QNetworkRequest(QUrl("https://api.github.com/repos/gridcoin/Gridcoin-Research/releases/latest"))); + +} + +void DiagnosticsDialog::clkFinished() { + time_t ntpTime; + + while(udpSocket->pendingDatagramSize() != -1) { + char recvBuffer[udpSocket->pendingDatagramSize()]; + udpSocket->readDatagram(&recvBuffer[0], 48, nullptr, nullptr); + if(sizeof(recvBuffer) == 48){ + int count= 40; + unsigned long DateTimeIn= uchar(recvBuffer[count])+ (uchar(recvBuffer[count+ 1]) << 8)+ (uchar(recvBuffer[count+ 2]) << 16)+ (uchar(recvBuffer[count+ 3]) << 24); + ntpTime = ntohl((time_t)DateTimeIn); + ntpTime -= 2208988800U; + } + } + + udpSocket->close(); + + boost::posix_time::ptime localTime = boost::posix_time::microsec_clock::universal_time(); + boost::posix_time::ptime networkTime = boost::posix_time::from_time_t(ntpTime); + + boost::posix_time::time_duration timeDiff = networkTime - localTime; + + if(timeDiff.minutes() < 3) + ui->varifyClkResultLbl->setText("Passed"); + else + ui->varifyClkResultLbl->setText("Failed (Sync local time with network)"); + + this->repaint(); +} + +void DiagnosticsDialog::TCPFinished() { + tcpSocket->close(); + ui->varifyTCPPortResultLbl->setText("Passed"); + this->repaint(); +} + +void DiagnosticsDialog::TCPFailed(QAbstractSocket::SocketError socket) { + ui->varifyTCPPortResultLbl->setText("Failed (Port 32749 may be blocked by your firewall)"); + this->repaint(); +} + +void DiagnosticsDialog::getGithubVersionFinished(QNetworkReply *reply) { + QByteArray data; + data = reply->readAll(); + std::string newVersionString; + + QJsonDocument replyJson = QJsonDocument::fromJson(data); + QJsonObject obj = replyJson.object(); + if(!obj.empty()) { + QJsonValue newVersionJVal = obj.value("name"); + if(!newVersionJVal.isUndefined()) { + newVersionString = newVersionJVal.toString().toStdString(); + } + } + + std::vector newVersionStringSplit; + boost::algorithm::split(newVersionStringSplit, newVersionString, boost::is_any_of("-")); + newVersionString = newVersionStringSplit.at(0); + + std::string currentVersionString = FormatFullVersion(); + std::vector currentVersionStringSplit; + boost::algorithm::split(currentVersionStringSplit, currentVersionString, boost::is_any_of("-")); + currentVersionString = currentVersionStringSplit.at(0); + boost::algorithm::split(currentVersionStringSplit, currentVersionString, boost::is_any_of("v")); + currentVersionString = currentVersionStringSplit.at(1); + + std::vector currentVersionList; + std::vector newVersionList; + + boost::algorithm::split(currentVersionList, currentVersionString, boost::is_any_of(".")); + boost::algorithm::split(newVersionList, newVersionString, boost::is_any_of(".")); + + int iNew; + int iCurrent; + for(unsigned int i=0; i iCurrent) { + ui->checkClientVersionResultLbl->setText("Failed (An update is available, please update)"); + return; + } else + ui->checkClientVersionResultLbl->setText("Up to date"); + } +} diff --git a/src/qt/diagnosticsdialog.h b/src/qt/diagnosticsdialog.h new file mode 100644 index 0000000000..ba8e87f675 --- /dev/null +++ b/src/qt/diagnosticsdialog.h @@ -0,0 +1,51 @@ +#ifndef DIAGNOSTICSDIALOG_H +#define DIAGNOSTICSDIALOG_H + +#include +#include + +#include + +namespace Ui { +class DiagnosticsDialog; +} + +class DiagnosticsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit DiagnosticsDialog(QWidget *parent = 0); + ~DiagnosticsDialog(); + +private: + Ui::DiagnosticsDialog *ui; + void GetData(); + int VarifyBoincPath(); + int VerifyCPIDIsInNeuralNetwork(); + int VarifyWalletIsSynced(); + int VarifyCPIDHasRAC(); + int VarifyAddNode(); + int VarifyIsCPIDValid(); + int FindCPID(); + void VarifyClock(); + void VarifyTCPPort(); + double GetTotalCPIDRAC(std::string cpid); + double GetUserRAC(std::string cpid, int *projects); + std::string KeyValue(std::string key); + + QUdpSocket *udpSocket; + QTcpSocket *tcpSocket; + QNetworkAccessManager *networkManager; + std::string testnet_flag; + std::string syncData; + +private slots: + void on_testBtn_clicked(); + void clkFinished(); + void TCPFinished(); + void TCPFailed(QAbstractSocket::SocketError socketError); + void getGithubVersionFinished(QNetworkReply *reply); +}; + +#endif // DIAGNOSTICSDIALOG_H diff --git a/src/qt/forms/diagnosticsdialog.ui b/src/qt/forms/diagnosticsdialog.ui new file mode 100644 index 0000000000..1a3f526066 --- /dev/null +++ b/src/qt/forms/diagnosticsdialog.ui @@ -0,0 +1,428 @@ + + + DiagnosticsDialog + + + + 0 + 0 + 757 + 388 + + + + Diagnostics + + + + 20 + + + 20 + + + 20 + + + 20 + + + + + QLayout::SetMinimumSize + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 8 + + + + + + 0 + 0 + + + + + 240 + 0 + + + + Verify CPID is in Neural Network + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + Verify BOINC path + + + + + + + Verify CPID has RAC + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + Verify wallet is synced + + + + + + + Verify CPID is valid + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + Find CPID + + + + + + + + 14 + + + + Diagnostics + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + Verify clock + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + Verify addnode + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + Verify TCP port 32749 + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + true + + + + + + + Check client version + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + + + + + + + + + 550 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Close + + + false + + + + + + + + 0 + 0 + + + + Test + + + + + + + + + + + cancelBtn + clicked() + DiagnosticsDialog + close() + + + 411 + 483 + + + 300 + 261 + + + + + From 9f9ece31720f24d626c6e2a6a5f43890dee1c520 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 12 Oct 2017 08:55:26 +0200 Subject: [PATCH 034/166] Dead code removal. --- src/global_objects_noui.hpp | 7 --- src/main.cpp | 85 +++---------------------------------- src/main.h | 2 - src/rpcblockchain.cpp | 10 ----- src/wallet.cpp | 6 --- 5 files changed, 5 insertions(+), 105 deletions(-) diff --git a/src/global_objects_noui.hpp b/src/global_objects_noui.hpp index d4d06d6e97..62d651f015 100755 --- a/src/global_objects_noui.hpp +++ b/src/global_objects_noui.hpp @@ -7,20 +7,13 @@ extern int nBoincUtilization; extern std::string sRegVer; extern int nRegVersion; -extern bool bDebugMode; -extern bool bBoincSubsidyEligible; extern bool bCPIDsLoaded; extern bool bProjectsInitialized; -extern int iCriticalThreadDelay; -extern bool CreatingNewBlock; extern bool bNetAveragesLoaded; extern bool bForceUpdate; extern bool bCheckedForUpgrade; extern bool bCheckedForUpgradeLive; extern bool bGlobalcomInitialized; -extern bool bAllowBackToBack; -extern bool CreatingCPUBlock; -extern bool bStakeMinerOutOfSyncWithNetwork; extern bool bDoTally; extern bool bTallyFinished; extern bool bGridcoinGUILoaded; diff --git a/src/main.cpp b/src/main.cpp index 44af383869..718891a70e 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,7 +60,6 @@ extern MiningCPID GetInitializedMiningCPID(std::string name, std::map mvTimers; // Contains event timers that reset after m // End of Gridcoin Global vars -bool bDebugMode = false; -bool bBoincSubsidyEligible = false; - ////////////////////////////////////////////////////////////////////////////// // // dispatching functions @@ -7006,21 +6999,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - -void AddPeek(std::string data) -{ - return; - std::string buffer = ToString(GetAdjustedTime()) + ":" + data + ""; - msPeek += buffer; - if (msPeek.length() > 60000) msPeek = ""; - if ((GetAdjustedTime() - nLastPeek) > 60) - { - if (fDebug) printf("\r\nLong Duration : %s\r\n",buffer.c_str()); - } - nLastPeek = GetAdjustedTime(); -} - - // requires LOCK(cs_vRecvMsg) bool ProcessMessages(CNode* pfrom) { @@ -7075,37 +7053,6 @@ bool ProcessMessages(CNode* pfrom) // Message size unsigned int nMessageSize = hdr.nMessageSize; - // Have a peek into what this node is doing - if (false && LessVerbose(100)) - { - std::string Peek = strCommand + ":" + RoundToString((double)nMessageSize,0) + " [" + NodeAddress(pfrom) + "]"; - AddPeek(Peek); - std::string sCurrentCommand = RoundToString((double)GetAdjustedTime(),0) + Peek; - std::string msLastNodeCommand = ReadCache("node_command",NodeAddress(pfrom)); - WriteCache("node_command",NodeAddress(pfrom),sCurrentCommand,GetAdjustedTime()); - if (msLastCommand == sCurrentCommand || (msLastNodeCommand == sCurrentCommand && !sCurrentCommand.empty())) - { - //Node Duplicates - double node_duplicates = cdbl(ReadCache("duplicates",NodeAddress(pfrom)),0) + 1; - WriteCache("duplicates",NodeAddress(pfrom),RoundToString(node_duplicates,0),GetAdjustedTime()); - if ((node_duplicates > 350 && !OutOfSyncByAge())) - { - printf(" Dupe (misbehaving) %s %s ",NodeAddress(pfrom).c_str(),Peek.c_str()); - pfrom->fDisconnect = true; - WriteCache("duplicates",NodeAddress(pfrom),"0",GetAdjustedTime()); - return false; - } - } - else - { - double node_duplicates = cdbl(ReadCache("duplicates",NodeAddress(pfrom)),0) - 15; - if (node_duplicates < 1) node_duplicates = 0; - WriteCache("duplicates",NodeAddress(pfrom),RoundToString(node_duplicates,0),GetAdjustedTime()); - } - msLastCommand = sCurrentCommand; - } - - // Checksum CDataStream& vRecv = msg.vRecv; uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize); @@ -7956,28 +7903,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // returns true if wasn't already contained in the set if (pto->setInventoryKnown.insert(inv).second) { - vInv.push_back(inv); - if (vInv.size() >= 1000) - { - if (false) - { - AddPeek("PushInv-Large " + RoundToString((double)vInv.size(),0)); - // If node has not been misbehaving (1-30-2016) then push it: (pto->nMisbehavior) && pto->NodeAddress().->addr.IsRoutable() - pto->PushMessage("inv", vInv); - AddPeek("Pushed Inv-Large " + RoundToString((double)vInv.size(),0)); - if (fDebug10) printf(" *PIL* "); - vInv.clear(); - if (TimerMain("PushInventoryLarge",50)) CleanInboundConnections(true); - // Eventually ban the node if they keep asking for inventory - TrackRequests(pto,"Inv-Large"); - AddPeek("Done with Inv-Large " + RoundToString((double)vInv.size(),0)); - } - else - { - pto->PushMessage("inv", vInv); - vInv.clear(); - } - + vInv.push_back(inv); + if (vInv.size() >= 1000) + { + pto->PushMessage("inv", vInv); + vInv.clear(); } } } @@ -7999,7 +7929,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (!AlreadyHave(txdb, inv)) { if (fDebugNet) printf("sending getdata: %s\n", inv.ToString().c_str()); - //AddPeek("Getdata " + inv.ToString()); vGetData.push_back(inv); if (vGetData.size() >= 1000) { @@ -8011,11 +7940,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->mapAskFor.erase(pto->mapAskFor.begin()); } if (!vGetData.empty()) - { pto->PushMessage("getdata", vGetData); - //AddPeek("GetData"); - } - } return true; } diff --git a/src/main.h b/src/main.h index 198bf1bf12..2586dca6d3 100755 --- a/src/main.h +++ b/src/main.h @@ -193,8 +193,6 @@ extern std::string msMiningErrors5; extern std::string msMiningErrors6; extern std::string msMiningErrors7; extern std::string msMiningErrors8; -extern std::string msPeek; -extern std::string msLastCommand; extern std::string msAttachmentGuid; extern std::string msMiningErrorsIncluded; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index e31d671a8a..1c6d5e2593 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -2078,16 +2078,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("Tally Network Averages",1)); results.push_back(entry); } - else if (sItem == "peek") - { - std::vector s = split(msPeek,""); - - for (int i = 0; i < ((int)(s.size()-1)); i++) - { - entry.push_back(Pair(s[i],i + 1)); - } - results.push_back(entry); - } else if (sItem == "encrypt") { //Encrypt a phrase diff --git a/src/wallet.cpp b/src/wallet.cpp index f5f5d11ecd..313c83edea 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -26,7 +26,6 @@ double cdbl(std::string s, int place); std::string SendReward(std::string sAddress, int64_t nAmount); extern double MintLimiter(double PORDiff,int64_t RSA_WEIGHT,std::string cpid,int64_t locktime); int64_t GetRSAWeightByCPID(std::string cpid); -void AddPeek(std::string data); MiningCPID DeserializeBoincBlock(std::string block); @@ -1117,10 +1116,7 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb) { uint256 hash = tx.GetHash(); if (!txdb.ContainsTx(hash)) - { RelayTransaction((CTransaction)tx, hash); - AddPeek("Relaying wallet transaction " + tx.GetHash().ToString()); - } } } if (!(IsCoinBase() || IsCoinStake())) @@ -1130,8 +1126,6 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb) { if (fDebug10) printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str()); RelayTransaction((CTransaction)*this, hash); - AddPeek("Relaying wallet transaction " + hash.ToString()); - } } } From 31fe835b5073863d73e7722dfec863d5d9cb974e Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 12 Oct 2017 09:21:53 +0200 Subject: [PATCH 035/166] Replace boost::shared_ptr with std::shared_ptr. --- src/fwd.h | 6 ++++++ src/init.cpp | 6 +++--- src/init.h | 4 ++-- src/util.cpp | 2 +- src/util.h | 4 ++-- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/fwd.h b/src/fwd.h index ac98af0c70..0153e7b737 100755 --- a/src/fwd.h +++ b/src/fwd.h @@ -1,5 +1,7 @@ #pragma once +#include + // Block data structures. class CBlock; class CBlockIndex; @@ -9,3 +11,7 @@ class CNetAddr; struct MiningCPID; struct StructCPID; struct StructCPIDCache; + +class ThreadHandler; +typedef std::shared_ptr ThreadHandlerPtr; + diff --git a/src/init.cpp b/src/init.cpp index 01b62fb726..c8aec65610 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -191,7 +191,7 @@ bool AppInit(int argc, char* argv[]) bool fRet = false; - boost::shared_ptr threads(new ThreadHandler); + ThreadHandlerPtr threads = std::make_shared(); try { @@ -414,7 +414,7 @@ bool InitSanityCheck(void) -void ThreadAppInit2(boost::shared_ptr th) +void ThreadAppInit2(ThreadHandlerPtr th) { // Make this thread recognisable RenameThread("grc-appinit2"); @@ -432,7 +432,7 @@ void ThreadAppInit2(boost::shared_ptr th) /** Initialize Gridcoin. * @pre Parameters should be parsed and config file should be read. */ -bool AppInit2(boost::shared_ptr threads) +bool AppInit2(ThreadHandlerPtr threads) { // ********************************************************* Step 1: setup #ifdef _MSC_VER diff --git a/src/init.h b/src/init.h index c8389a2299..9b8a768f87 100644 --- a/src/init.h +++ b/src/init.h @@ -14,8 +14,8 @@ void StartShutdown(); bool ShutdownRequested(); void Shutdown(void* parg); -bool AppInit2(boost::shared_ptr threads); -void ThreadAppInit2(boost::shared_ptr th); +bool AppInit2(ThreadHandlerPtr threads); +void ThreadAppInit2(ThreadHandlerPtr th); std::string HelpMessage(); std::string LogSomething(); diff --git a/src/util.cpp b/src/util.cpp index 14fcdffb05..b43af441d5 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1601,7 +1601,7 @@ std::string MakeSafeMessage(const std::string& messagestring) return safemessage; } -bool ThreadHandler::createThread(void(*pfn)(boost::shared_ptr), boost::shared_ptr parg, const std::string tname) +bool ThreadHandler::createThread(void(*pfn)(ThreadHandlerPtr), ThreadHandlerPtr parg, const std::string tname) { try { diff --git a/src/util.h b/src/util.h index 62f6fef648..3d7edbc22f 100644 --- a/src/util.h +++ b/src/util.h @@ -7,6 +7,7 @@ #define BITCOIN_UTIL_H #include "uint256.h" +#include "fwd.h" #ifndef WIN32 #include @@ -627,8 +628,7 @@ class ThreadHandler { public: ThreadHandler(){}; - ~ThreadHandler(){}; - bool createThread(void(*pfn)(boost::shared_ptr), boost::shared_ptr parg, const std::string tname); + bool createThread(void(*pfn)(ThreadHandlerPtr), ThreadHandlerPtr parg, const std::string tname); bool createThread(void(*pfn)(void*), void* parg, const std::string tname); int numThreads(); bool threadExists(const std::string tname); From 1cb5b758768ad26faa9936111751315f0c0fcc73 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 14 Oct 2017 11:52:57 +0200 Subject: [PATCH 036/166] Build error fix. --- src/qt/bitcoin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 54468fbf9a..5dd9ee7dbe 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -150,7 +150,7 @@ int main(int argc, char *argv[]) // Set default value to exit properly. Exit code 42 will trigger restart of the wallet. int currentExitCode = 0; - boost::shared_ptr threads(new ThreadHandler); + std::shared_ptr threads = std::make_shared(); // Do this early as we don't want to bother initializing if we are just calling IPC ipcScanRelay(argc, argv); From d2a16ccea7fa71393e1cd687ef84611d129e90ca Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 15 Oct 2017 07:53:02 +0200 Subject: [PATCH 037/166] Remove AutoSelectSyncCheckpoint and just use GetLastCheckpoint. --- src/checkpoints.cpp | 14 ++------------ src/checkpoints.h | 1 - src/main.cpp | 15 +++++++++------ src/rpcblockchain.cpp | 17 +++++++++-------- 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 354efbcd42..f85a47a104 100755 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -91,22 +91,12 @@ namespace Checkpoints return NULL; } - // Automatically select a suitable sync-checkpoint - const CBlockIndex* AutoSelectSyncCheckpoint() - { - const CBlockIndex *pindex = pindexBest; - // Search backward for a block within max span and maturity window - while (pindex->pprev && pindex->nHeight + nCheckpointSpan > pindexBest->nHeight) - pindex = pindex->pprev; - return pindex; - } - // Check against synchronized checkpoint bool CheckSync(int nHeight) { - const CBlockIndex* pindexSync = AutoSelectSyncCheckpoint(); + const CBlockIndex* pindexSync = GetLastCheckpoint(mapBlockIndex); - if (nHeight <= pindexSync->nHeight) + if (pindexSync != NULL && nHeight <= pindexSync->nHeight) return false; return true; } diff --git a/src/checkpoints.h b/src/checkpoints.h index 33563074ea..8e2c5909b3 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -25,7 +25,6 @@ namespace Checkpoints // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint CBlockIndex* GetLastCheckpoint(const std::map& mapBlockIndex); - const CBlockIndex* AutoSelectSyncCheckpoint(); bool CheckSync(int nHeight); } diff --git a/src/main.cpp b/src/main.cpp index 718891a70e..5664c5af51 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4567,13 +4567,16 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) if (pblock->hashPrevBlock != hashBestChain) { // Extra checks to prevent "fill up memory by spamming with bogus blocks" - const CBlockIndex* pcheckpoint = Checkpoints::AutoSelectSyncCheckpoint(); - int64_t deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime; - if (deltaTime < 0) + const CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); + if(pcheckpoint != NULL) { - if (pfrom) - pfrom->Misbehaving(1); - return error("ProcessBlock() : block with timestamp before last checkpoint"); + int64_t deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime; + if (deltaTime < 0) + { + if (pfrom) + pfrom->Misbehaving(1); + return error("ProcessBlock() : block with timestamp before last checkpoint"); + } } } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 1c6d5e2593..928335881b 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -4391,16 +4391,17 @@ Value getcheckpoint(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( - "getcheckpoint\n" - "Show info of synchronized checkpoint.\n"); + "getcheckpoint\n" + "Show info of synchronized checkpoint.\n"); Object result; - const CBlockIndex* pindexCheckpoint = Checkpoints::AutoSelectSyncCheckpoint(); - - result.push_back(Pair("synccheckpoint", pindexCheckpoint->GetBlockHash().ToString().c_str())); - result.push_back(Pair("height", pindexCheckpoint->nHeight)); - result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str())); - result.push_back(Pair("policy", "rolling")); + const CBlockIndex* pindexCheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); + if(pindexCheckpoint != NULL) + { + result.push_back(Pair("synccheckpoint", pindexCheckpoint->GetBlockHash().ToString().c_str())); + result.push_back(Pair("height", pindexCheckpoint->nHeight)); + result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str())); + } return result; } From d7f46c746dbe6cf57f3913a465e7d06ea3f9277d Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 15 Oct 2017 16:22:00 +0200 Subject: [PATCH 038/166] Remove peer discovery via IRC. We now have to rely on manual peer entries for testnet. --- gridcoinresearch.pro | 2 - src/Makefile.include.objs | 1 - src/init.cpp | 5 - src/irc.cpp | 413 -------------------------------------- src/irc.h | 12 -- src/net.cpp | 8 +- src/net.h | 1 - 7 files changed, 1 insertion(+), 441 deletions(-) delete mode 100644 src/irc.cpp delete mode 100644 src/irc.h diff --git a/gridcoinresearch.pro b/gridcoinresearch.pro index 5be69aa413..156b4ee142 100755 --- a/gridcoinresearch.pro +++ b/gridcoinresearch.pro @@ -223,7 +223,6 @@ HEADERS += src/qt/bitcoingui.h \ src/walletdb.h \ src/script.h \ src/init.h \ - src/irc.h \ src/mruset.h \ src/json/json_spirit_writer_template.h \ src/json/json_spirit_writer.h \ @@ -304,7 +303,6 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/miner.cpp \ src/init.cpp \ src/net.cpp \ - src/irc.cpp \ src/checkpoints.cpp \ src/addrman.cpp \ src/db.cpp \ diff --git a/src/Makefile.include.objs b/src/Makefile.include.objs index 656643feea..b69c0217b8 100755 --- a/src/Makefile.include.objs +++ b/src/Makefile.include.objs @@ -8,7 +8,6 @@ OBJS= \ obj/key.o \ obj/db.o \ obj/init.o \ - obj/irc.o \ obj/keystore.o \ obj/miner.o \ obj/main.o \ diff --git a/src/init.cpp b/src/init.cpp index c8aec65610..c6efc137c5 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -328,7 +328,6 @@ std::string HelpMessage() " -externalip= " + _("Specify your own public address") + "\n" + " -onlynet= " + _("Only connect to nodes in network (IPv4, IPv6 or Tor)") + "\n" + " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" + - " -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" + " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" + " -bind= " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" + " -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" + @@ -504,11 +503,7 @@ bool AppInit2(ThreadHandlerPtr threads) nMinerSleep = GetArg("-minersleep", 8000); nDerivationMethodIndex = 0; - fTestNet = GetBoolArg("-testnet"); - if (fTestNet) { - SoftSetBoolArg("-irc", true); - } if (mapArgs.count("-bind")) { // when specifying an explicit binding address, you want to listen on it diff --git a/src/irc.cpp b/src/irc.cpp deleted file mode 100644 index 6395f827b2..0000000000 --- a/src/irc.cpp +++ /dev/null @@ -1,413 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "irc.h" -#include "net.h" -#include "strlcpy.h" -#include "base58.h" - -using namespace std; -using namespace boost; - -int nGotIRCAddresses = 0; - -void ThreadIRCSeed2(void* parg); - - - - -#pragma pack(push, 1) -struct ircaddr -{ - struct in_addr ip; - short port; -}; -#pragma pack(pop) - -string EncodeAddress(const CService& addr) -{ - struct ircaddr tmp; - if (addr.GetInAddr(&tmp.ip)) - { - tmp.port = htons(addr.GetPort()); - - vector vch(UBEGIN(tmp), UEND(tmp)); - return string("u") + EncodeBase58Check(vch); - } - return ""; -} - -bool DecodeAddress(string str, CService& addr) -{ - vector vch; - if (!DecodeBase58Check(str.substr(1), vch)) - return false; - - struct ircaddr tmp; - if (vch.size() != sizeof(tmp)) - return false; - memcpy(&tmp, &vch[0], sizeof(tmp)); - - addr = CService(tmp.ip, ntohs(tmp.port)); - return true; -} - - - - - - -static bool Send(SOCKET hSocket, const char* pszSend) -{ - if (strstr(pszSend, "PONG") != pszSend) - printf("IRC SENDING: %s\n", pszSend); - const char* psz = pszSend; - const char* pszEnd = psz + strlen(psz); - while (psz < pszEnd) - { - int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL); - if (ret < 0) - return false; - psz += ret; - } - return true; -} - -bool RecvLineIRC(SOCKET hSocket, string& strLine) -{ - while (true) - { - bool fRet = RecvLine(hSocket, strLine); - if (fRet) - { - if (fShutdown) - return false; - vector vWords; - ParseString(strLine, ' ', vWords); - if (vWords.size() >= 1 && vWords[0] == "PING") - { - strLine[1] = 'O'; - strLine += '\r'; - Send(hSocket, strLine.c_str()); - continue; - } - } - return fRet; - } -} - -int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL, const char* psz4=NULL) -{ - while (true) - { - string strLine; - strLine.reserve(10000); - if (!RecvLineIRC(hSocket, strLine)) - return 0; - printf("IRC %s\n", strLine.c_str()); - if (psz1 && strLine.find(psz1) != string::npos) - return 1; - if (psz2 && strLine.find(psz2) != string::npos) - return 2; - if (psz3 && strLine.find(psz3) != string::npos) - return 3; - if (psz4 && strLine.find(psz4) != string::npos) - return 4; - } -} - -bool Wait(int nSeconds) -{ - if (fShutdown) - return false; - printf("IRC waiting %d seconds to reconnect\n", nSeconds); - for (int i = 0; i < nSeconds; i++) - { - if (fShutdown) - return false; - MilliSleep(1000); - } - return true; -} - -bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet) -{ - strRet.clear(); - while (true) - { - string strLine; - if (!RecvLineIRC(hSocket, strLine)) - return false; - - vector vWords; - ParseString(strLine, ' ', vWords); - if (vWords.size() < 2) - continue; - - if (vWords[1] == psz1) - { - printf("IRC %s\n", strLine.c_str()); - strRet = strLine; - return true; - } - } -} - -bool GetIPFromIRC(SOCKET hSocket, string strMyName, CNetAddr& ipRet) -{ - Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str()); - - string strLine; - if (!RecvCodeLine(hSocket, "302", strLine)) - return false; - - vector vWords; - ParseString(strLine, ' ', vWords); - if (vWords.size() < 4) - return false; - - string str = vWords[3]; - if (str.rfind("@") == string::npos) - return false; - string strHost = str.substr(str.rfind("@")+1); - - // Hybrid IRC used by lfnet always returns IP when you userhost yourself, - // but in case another IRC is ever used this should work. - printf("GetIPFromIRC() got userhost %s\n", strHost.c_str()); - CNetAddr addr(strHost, true); - if (!addr.IsValid()) - return false; - ipRet = addr; - - return true; -} - - - -void ThreadIRCSeed(void* parg) -{ - // Make this thread recognisable as the IRC seeding thread - RenameThread("grc-ircseed"); - - try - { - ThreadIRCSeed2(parg); - } - catch (std::exception& e) - { - PrintExceptionContinue(&e, "ThreadIRCSeed()"); - } - catch(boost::thread_interrupted&) - { - printf("ThreadIRCSeed exited (interrupt)\r\n"); - return; - } - catch (...) - { - PrintExceptionContinue(NULL, "ThreadIRCSeed()"); - } - printf("ThreadIRCSeed exited\r\n"); -} - -void ThreadIRCSeed2(void* parg) -{ - // Don't connect to IRC if we won't use IPv4 connections. - if (IsLimited(NET_IPV4)) - return; - - // ... or if we won't make outbound connections and won't accept inbound ones. - if (mapArgs.count("-connect") && fNoListen) - return; - - // ... or if IRC is not enabled. - if (!GetBoolArg("-irc", false)) - return; - - printf("ThreadIRCSeed started\n"); - int nErrorWait = 10; - int nRetryWait = 10; - int nNameRetry = 0; - - while (!fShutdown) - { - CService addrConnect("92.243.23.21", 6667); // irc.lfnet.org - - CService addrIRC("irc.lfnet.org", 6667, true); - if (addrIRC.IsValid()) - addrConnect = addrIRC; - - SOCKET hSocket; - if (!ConnectSocket(addrConnect, hSocket)) - { - if (fDebug10) printf("IRC connection problem \r\n"); - nErrorWait = nErrorWait * 11 / 10; - if (Wait(nErrorWait += 60)) - continue; - else - return; - } - - if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname")) - { - closesocket(hSocket); - hSocket = INVALID_SOCKET; - nErrorWait = nErrorWait * 11 / 10; - if (Wait(nErrorWait += 60)) - continue; - else - return; - } - - CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses - CService addrLocal; - string strMyName; - // Don't use our IP as our nick if we're not listening - // or if it keeps failing because the nick is already in use. - if (!fNoListen && GetLocal(addrLocal, &addrIPv4) && nNameRetry<3) - strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); - if (strMyName == "") - strMyName = strprintf("x%" PRIu64 "", GetRand(1000000000)); - - Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); - Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); - - int nRet = RecvUntil(hSocket, " 004 ", " 433 "); - if (nRet != 1) - { - closesocket(hSocket); - hSocket = INVALID_SOCKET; - if (nRet == 2) - { - printf("IRC name already in use\n"); - nNameRetry++; - Wait(10); - continue; - } - nErrorWait = nErrorWait * 11 / 10; - if (Wait(nErrorWait += 60)) - continue; - else - return; - } - nNameRetry = 0; - MilliSleep(500); - - // Get our external IP from the IRC server and re-nick before joining the channel - CNetAddr addrFromIRC; - if (GetIPFromIRC(hSocket, strMyName, addrFromIRC)) - { - printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str()); - // Don't use our IP as our nick if we're not listening - if (!fNoListen && addrFromIRC.IsRoutable()) - { - // IRC lets you to re-nick - AddLocal(addrFromIRC, LOCAL_IRC); - strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); - Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); - } - } - - if (fTestNet) { - Send(hSocket, "JOIN #gridcoinTEST\r"); - Send(hSocket, "WHO #gridcoinTEST\r"); - } else { - // randomly join #gridcoin00-#gridcoin05 - int channel_number = GetRandInt(5); - - // Channel number is always 0 for initial release - //int channel_number = 0; - Send(hSocket, strprintf("JOIN #gridcoin%02d\r", channel_number).c_str()); - Send(hSocket, strprintf("WHO #gridcoin%02d\r", channel_number).c_str()); - } - - int64_t nStart = GetTime(); - string strLine; - strLine.reserve(10000); - while (!fShutdown && RecvLineIRC(hSocket, strLine)) - { - if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') - continue; - - vector vWords; - ParseString(strLine, ' ', vWords); - if (vWords.size() < 2) - continue; - - char pszName[10000]; - pszName[0] = '\0'; - - if (vWords[1] == "352" && vWords.size() >= 8) - { - // index 7 is limited to 16 characters - // could get full length name at index 10, but would be different from join messages - strlcpy(pszName, vWords[7].c_str(), sizeof(pszName)); - if (fDebug10) printf("IRC got who\n"); - } - - if (vWords[1] == "JOIN" && vWords[0].size() > 1) - { - // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname - strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName)); - if (strchr(pszName, '!')) - *strchr(pszName, '!') = '\0'; - printf("IRC got join\n"); - } - - if (pszName[0] == 'u') - { - CAddress addr; - if (DecodeAddress(pszName, addr)) - { - addr.nTime = GetAdjustedTime(); - if (addrman.Add(addr, addrConnect, 51 * 60)) - printf("IRC got new address: %s\n", addr.ToString().c_str()); - nGotIRCAddresses++; - } - else - { - printf("IRC decode failed\n"); - } - } - } - closesocket(hSocket); - hSocket = INVALID_SOCKET; - - if (GetTime() - nStart > 20 * 60) - { - nErrorWait /= 3; - nRetryWait /= 3; - } - - nRetryWait = nRetryWait * 11 / 10; - if (!Wait(nRetryWait += 60)) - return; - } -} - - - - - - - - - - -#ifdef TEST -int main(int argc, char *argv[]) -{ - WSADATA wsadata; - if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR) - { - printf("Error at WSAStartup()\n"); - return false; - } - - ThreadIRCSeed(NULL); - - WSACleanup(); - return 0; -} -#endif diff --git a/src/irc.h b/src/irc.h deleted file mode 100644 index 119aeb3fda..0000000000 --- a/src/irc.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_IRC_H -#define BITCOIN_IRC_H - -void ThreadIRCSeed(void* parg); - -extern int nGotIRCAddresses; - -#endif diff --git a/src/net.cpp b/src/net.cpp index 93abaea213..6f5ca89ec8 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3,7 +3,6 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "irc.h" #include "db.h" #include "net.h" #include "init.h" @@ -476,7 +475,6 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha return error("GetMyExternalIP() : connection closed"); } -// We now get our external IP from the IRC server first and only use this as a backup bool GetMyExternalIP(CNetAddr& ipRet) { CService addrConnect; @@ -1822,7 +1820,7 @@ void ThreadOpenConnections2(void* parg) if (fShutdown) return; - // Add seed nodes if IRC isn't working + // Add seed nodes if (addrman.size()==0 && (GetAdjustedTime() - nStart > 60) && !fTestNet) { std::vector vAdd; @@ -2305,10 +2303,6 @@ void StartNode(void* parg) if (fUseUPnP) MapPort(); - // Get addresses from IRC and advertise ours - if (!netThreads->createThread(ThreadIRCSeed,NULL,"ThreadIRCSeed")) - printf("Error: createThread(ThreadIRCSeed) failed\r\n"); - // Send and receive from sockets, accept connections if (!netThreads->createThread(ThreadSocketHandler,NULL,"ThreadSocketHandler")) printf("Error: createThread(ThreadSocketHandler) failed\r\n"); diff --git a/src/net.h b/src/net.h index 2da240123b..65b3c92804 100644 --- a/src/net.h +++ b/src/net.h @@ -58,7 +58,6 @@ enum LOCAL_IF, // address a local interface listens on LOCAL_BIND, // address explicit bound to LOCAL_UPNP, // address reported by UPnP - LOCAL_IRC, // address reported by IRC (deprecated) LOCAL_HTTP, // address reported by whatismyip.com and similar LOCAL_MANUAL, // address explicitly specified (-externalip=) From 68b0d7bc20b8b5ef161badce3d8e6d35fa83a25f Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 9 Oct 2017 13:51:10 +0200 Subject: [PATCH 039/166] Remove unnecessary lexical_cast include. --- src/rpcblockchain.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 928335881b..35a21e9bf7 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -17,7 +17,6 @@ #include #include -#include #include // for to_lower() #include #include From 6c22687f6e280f98a5d96b1f31079f589c6b7ad1 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 9 Oct 2017 13:53:34 +0200 Subject: [PATCH 040/166] Remove cdbl forwards. --- src/rpcblockchain.cpp | 1 - src/wallet.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 35a21e9bf7..2cf5574739 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -142,7 +142,6 @@ extern Array MagnitudeReportCSV(bool detail); std::string getfilecontents(std::string filename); int CreateRestorePoint(); int DownloadBlocks(); -double cdbl(std::string s, int place); double LederstrumpfMagnitude2(double mag,int64_t locktime); bool IsCPIDValidv2(MiningCPID& mc, int height); std::string RetrieveMd5(std::string s1); diff --git a/src/wallet.cpp b/src/wallet.cpp index 313c83edea..926e6a4f60 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -22,7 +22,6 @@ using namespace std; -double cdbl(std::string s, int place); std::string SendReward(std::string sAddress, int64_t nAmount); extern double MintLimiter(double PORDiff,int64_t RSA_WEIGHT,std::string cpid,int64_t locktime); int64_t GetRSAWeightByCPID(std::string cpid); From a84ca51eb16b87b25a0d8a530023684c72d1bdf0 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 9 Oct 2017 13:58:37 +0200 Subject: [PATCH 041/166] Newline normalization. --- src/test/block_tests.cpp | 140 +++++++++++++++++++-------------------- src/test/cpid_tests.cpp | 34 +++++----- 2 files changed, 87 insertions(+), 87 deletions(-) diff --git a/src/test/block_tests.cpp b/src/test/block_tests.cpp index 15899e9411..9ef2b27f31 100755 --- a/src/test/block_tests.cpp +++ b/src/test/block_tests.cpp @@ -1,70 +1,70 @@ -#include "main.h" -#include "block.h" - -#include -#include -#include - -namespace -{ - template - class BlockChain - { - public: - BlockChain() - { - // Initialize block link. - for(auto block = blocks.begin(); block != blocks.end(); ++block) - { - CBlockIndex& prev = *std::prev(block); - CBlockIndex& next = *std::next(block); - if(block != &blocks.front()) - { - block->pprev = &prev; - block->nHeight = prev.nHeight + 1; - } - if(block != &blocks.back()) - block->pnext = &next; - } - - // Setup global variables. - pindexBest = &blocks.back(); - pindexGenesisBlock = &blocks.front(); - nBestHeight = blocks.back().nHeight; - } - - std::array blocks; - }; -} - -BOOST_AUTO_TEST_SUITE(block_tests); - -BOOST_AUTO_TEST_CASE(FindBlockInNormalChainShouldWork) -{ - BlockChain<100> chain; - BlockFinder finder; - - for(auto& block : chain.blocks) - BOOST_CHECK_EQUAL(&block, finder.FindByHeight(block.nHeight)); -} - -BOOST_AUTO_TEST_CASE(FindBlockAboveHighestHeightShouldReturnHighestBlock) -{ - BlockChain<100> chain; - BlockFinder finder; - - CBlockIndex& last = chain.blocks.back(); - BOOST_CHECK_EQUAL(&last, finder.FindByHeight(101)); -} - -BOOST_AUTO_TEST_CASE(FindBlockByHeightShouldWorkOnChainsWithJustOneBlock) -{ - BlockChain<1> chain; - BlockFinder finder; - - BOOST_CHECK_EQUAL(&chain.blocks.front(), finder.FindByHeight(0)); - BOOST_CHECK_EQUAL(&chain.blocks.front(), finder.FindByHeight(1)); - BOOST_CHECK_EQUAL(&chain.blocks.front(), finder.FindByHeight(-1)); -} - -BOOST_AUTO_TEST_SUITE_END() +#include "main.h" +#include "block.h" + +#include +#include +#include + +namespace +{ + template + class BlockChain + { + public: + BlockChain() + { + // Initialize block link. + for(auto block = blocks.begin(); block != blocks.end(); ++block) + { + CBlockIndex& prev = *std::prev(block); + CBlockIndex& next = *std::next(block); + if(block != &blocks.front()) + { + block->pprev = &prev; + block->nHeight = prev.nHeight + 1; + } + if(block != &blocks.back()) + block->pnext = &next; + } + + // Setup global variables. + pindexBest = &blocks.back(); + pindexGenesisBlock = &blocks.front(); + nBestHeight = blocks.back().nHeight; + } + + std::array blocks; + }; +} + +BOOST_AUTO_TEST_SUITE(block_tests); + +BOOST_AUTO_TEST_CASE(FindBlockInNormalChainShouldWork) +{ + BlockChain<100> chain; + BlockFinder finder; + + for(auto& block : chain.blocks) + BOOST_CHECK_EQUAL(&block, finder.FindByHeight(block.nHeight)); +} + +BOOST_AUTO_TEST_CASE(FindBlockAboveHighestHeightShouldReturnHighestBlock) +{ + BlockChain<100> chain; + BlockFinder finder; + + CBlockIndex& last = chain.blocks.back(); + BOOST_CHECK_EQUAL(&last, finder.FindByHeight(101)); +} + +BOOST_AUTO_TEST_CASE(FindBlockByHeightShouldWorkOnChainsWithJustOneBlock) +{ + BlockChain<1> chain; + BlockFinder finder; + + BOOST_CHECK_EQUAL(&chain.blocks.front(), finder.FindByHeight(0)); + BOOST_CHECK_EQUAL(&chain.blocks.front(), finder.FindByHeight(1)); + BOOST_CHECK_EQUAL(&chain.blocks.front(), finder.FindByHeight(-1)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/cpid_tests.cpp b/src/test/cpid_tests.cpp index 925e8b99c0..d98e8c1de1 100755 --- a/src/test/cpid_tests.cpp +++ b/src/test/cpid_tests.cpp @@ -1,17 +1,17 @@ -#include "cpid.h" - -#include - -BOOST_AUTO_TEST_SUITE(cpid_tests); - -#include - -BOOST_AUTO_TEST_CASE(cpid_VerifyComputeCPIDv2) -{ - uint256 blockhash = 1; - BOOST_CHECK_EQUAL( - ComputeCPIDv2("test@unittest.com", "abcdefghijklmno", blockhash), - "4078bd252856710b95c4f31377bb1ba86bc3666ac7676a706e736ece7176d4756a7b76417ad36cd97a6976d78fc5d0d2"); -} - -BOOST_AUTO_TEST_SUITE_END() +#include "cpid.h" + +#include + +BOOST_AUTO_TEST_SUITE(cpid_tests); + +#include + +BOOST_AUTO_TEST_CASE(cpid_VerifyComputeCPIDv2) +{ + uint256 blockhash = 1; + BOOST_CHECK_EQUAL( + ComputeCPIDv2("test@unittest.com", "abcdefghijklmno", blockhash), + "4078bd252856710b95c4f31377bb1ba86bc3666ac7676a706e736ece7176d4756a7b76417ad36cd97a6976d78fc5d0d2"); +} + +BOOST_AUTO_TEST_SUITE_END() From f91355b832fba6defd71e5c65a2e439182acb7d2 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Wed, 11 Oct 2017 08:54:12 +0200 Subject: [PATCH 042/166] Replace cdbl implementation with atof+round. I checked 22 million cdbl calls while syncing and none of them required cleaning. The new implementation uses 18% of the execution time compared to the old one. This is negligleble on modern hardware, but an old Raspbeery Pi should see a greater boost. --- src/main.cpp | 16 +--------------- src/test/gridcoin_tests.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 17 deletions(-) mode change 100644 => 100755 src/test/gridcoin_tests.cpp diff --git a/src/main.cpp b/src/main.cpp index 5664c5af51..e5fc1c3be4 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,6 @@ #include "miner.h" #include "backup.h" -#include #include #include #include @@ -4973,22 +4972,9 @@ std::string RetrieveMd5(std::string s1) } } - double cdbl(std::string s, int place) { - if (s=="") s="0"; - s = strReplace(s,"\r",""); - s = strReplace(s,"\n",""); - s = strReplace(s,"a",""); - s = strReplace(s,"a",""); - s = strReplace(s,"b",""); - s = strReplace(s,"c",""); - s = strReplace(s,"d",""); - s = strReplace(s,"e",""); - s = strReplace(s,"f",""); - double r = lexical_cast(s); - double d = Round(r,place); - return d; + return Round(atof(s.c_str()), place); } diff --git a/src/test/gridcoin_tests.cpp b/src/test/gridcoin_tests.cpp old mode 100644 new mode 100755 index 8132e1e9d0..90d156b013 --- a/src/test/gridcoin_tests.cpp +++ b/src/test/gridcoin_tests.cpp @@ -16,6 +16,7 @@ extern std::string UnpackBinarySuperblock(std::string sBlock); extern std::string ConvertHexToBin(std::string a); extern std::string ConvertBinToHex(std::string a); extern bool fTestNet; +double cdbl(std::string s, int place); namespace { @@ -74,13 +75,11 @@ BOOST_AUTO_TEST_CASE(gridcoin_GetOutstandingAmountOwedShouldReturnCorrectSum) BOOST_AUTO_TEST_CASE(gridcoin_VerifyGetQuorumHash) { const std::string contract = "0390450eff5f5cd6d7a7d95a6d898d8d,1480;1878ecb566ac8e62beb7d141e1922460,6.25;1963a6f109ea770c195a0e1afacd2eba,70;285ff8d5014ef73cc83580338a9c0345,820;46f64d69eb8c5ee9cd24178b589af83f,12.5;0,15;4f0fecd04be3a74c46aa9678f780d028,750;55cd02be28521073d367f7ca38615682,720;58e565221db80d168621187c36c26c3e,12.5;59900fe7ef44fe33aa2afdf98301ec1c,530;5a094d7d93f6d6370e78a2ac8c008407,1400;0,15;7d0d73fe026d66fd4ab8d5d8da32a611,84000;8cfe9864e18db32a334b7de997f5a4f2,35;8f2a530cf6f73647af4c680c3471ea65,90;96c18bb4a02d15c90224a7138a540cf7,4520;9b67756a05f76842de1e88226b79deb9,0;9ce6f19e20f69790601c9bf9c0b03928,3.75;9ff2b091f67327b7d8e5b75fb5337514,310;a7a537ff8ad4d8fff4b3dad444e681ef,0;a914eba952be5dfcf73d926b508fd5fa,6720;d5924e4750f0f1c1c97b9635914afb9e,0;db250f4451dc39632e52e157f034316d,5;e7f90818e3e87c0bbefe83ad3cfe27e1,13500;btc,0;grc,0;amicable numbers,536000,5900000;asteroids@home,158666.67,793333.33;citizen science grid,575333.33,2881428.57;collatz conjecture,4027142.86,36286380;cosmology@home,47000,282666.67;einstein@home,435333.33,5661428.57;gpugrid,1804285.71,9035714.29;leiden classical,2080,10500;lhc@home classic,26166.67,210000;milkyway@home,2094285.71,8395714.29;moowrap,996666.67,7981428.57;nfs@home,96000,385333.33;numberfields@home,89333.33,626666.67;primegrid,248000,1735714.29;seti@home,52333.33,367333.33;srbase,89666.67,896666.67;sztaki desktop grid,8320,41666.67;theskynet pogs,45500,409333.33;tn-grid,39500,514666.67;universe@home,47833.33,335333.33;vgtu project@home,20666.67,124000;world community grid,29166.67,263333.33;yafu,93000,838666.67;yoyo@home,7040,56333.33;NeuralNetwork,2000000,20000000;"; - //const std::string contract = "0390450eff5f5cd6d7a7d95a6d898d8d,1480;1878ecb566ac8e62beb7d141e1922460,5;1963a6f109ea770c195a0e1afacd2eba,80;285ff8d5014ef73cc83580338a9c0345,780;46f64d69eb8c5ee9cd24178b589af83f,11.25;0,15;4f0fecd04be3a74c46aa9678f780d028,580;55cd02be28521073d367f7ca38615682,780;58e565221db80d168621187c36c26c3e,12.5;59900fe7ef44fe33aa2afdf98301ec1c,530;5a094d7d93f6d6370e78a2ac8c008407,1200;0,15;7d0d73fe026d66fd4ab8d5d8da32a611,80666.67;8cfe9864e18db32a334b7de997f5a4f2,30;8f2a530cf6f73647af4c680c3471ea65,70;96c18bb4a02d15c90224a7138a540cf7,4560;0,15;9ce6f19e20f69790601c9bf9c0b03928,3.75;9ff2b091f67327b7d8e5b75fb5337514,235;a7a537ff8ad4d8fff4b3dad444e681ef,0;a914eba952be5dfcf73d926b508fd5fa,10166.67;0,15;db250f4451dc39632e52e157f034316d,3.75;e7f90818e3e87c0bbefe83ad3cfe27e1,13666.67;f46d4755f17cfaed68bf7af707b1731e,21.25;btc,0;grc,0;amicable numbers,640666.67,7054285.71;asteroids@home,161333.33,809333.33;citizen science grid,587333.33,2944285.71;collatz conjecture,4391428.57,39564960;cosmology@home,43666.67,306000;einstein@home,464000,6498571.43;gpugrid,1377142.86,6897142.86;leiden classical,1560,9280;lhc@home classic,34500,276000;milkyway@home,2237142.86,8970000;moowrap,1105714.29,8858571.43;nfs@home,106666.67,428000;numberfields@home,117333.33,704666.67;primegrid,320666.67,1927142.86;seti@home,50000,401333.33;srbase,93333.33,932666.67;sztaki desktop grid,7920,39666.67;theskynet pogs,48166.67,434666.67;tn-grid,43500,522666.67;universe@home,54666.67,384000;vgtu project@home,21000,126000;world community grid,30000,270666.67;yafu,100000,901333.33;yoyo@home,7640,53666.67;NeuralNetwork,2000000,20000000;"; BOOST_CHECK_EQUAL(GetQuorumHash(contract), "0f099cab261bb562ff553f3b9c7bf942"); } BOOST_AUTO_TEST_CASE(gridcoin_QuorumHashShouldBeCorrectAfterPackingAndUnpackingBinarySuperblock) { - //const std::string contract = "0390450eff5f5cd6d7a7d95a6d898d8d,1480;1878ecb566ac8e62beb7d141e1922460,6.25;1963a6f109ea770c195a0e1afacd2eba,70;285ff8d5014ef73cc83580338a9c0345,820;46f64d69eb8c5ee9cd24178b589af83f,12.5;0,15;4f0fecd04be3a74c46aa9678f780d028,750;55cd02be28521073d367f7ca38615682,720;58e565221db80d168621187c36c26c3e,12.5;59900fe7ef44fe33aa2afdf98301ec1c,530;5a094d7d93f6d6370e78a2ac8c008407,1400;0,15;7d0d73fe026d66fd4ab8d5d8da32a611,84000;8cfe9864e18db32a334b7de997f5a4f2,35;8f2a530cf6f73647af4c680c3471ea65,90;96c18bb4a02d15c90224a7138a540cf7,4520;9b67756a05f76842de1e88226b79deb9,0;9ce6f19e20f69790601c9bf9c0b03928,3.75;9ff2b091f67327b7d8e5b75fb5337514,310;a7a537ff8ad4d8fff4b3dad444e681ef,0;a914eba952be5dfcf73d926b508fd5fa,6720;d5924e4750f0f1c1c97b9635914afb9e,0;db250f4451dc39632e52e157f034316d,5;e7f90818e3e87c0bbefe83ad3cfe27e1,13500;btc,0;grc,0;amicable numbers,536000,5900000;asteroids@home,158666.67,793333.33;citizen science grid,575333.33,2881428.57;collatz conjecture,4027142.86,36286380;cosmology@home,47000,282666.67;einstein@home,435333.33,5661428.57;gpugrid,1804285.71,9035714.29;leiden classical,2080,10500;lhc@home classic,26166.67,210000;milkyway@home,2094285.71,8395714.29;moowrap,996666.67,7981428.57;nfs@home,96000,385333.33;numberfields@home,89333.33,626666.67;primegrid,248000,1735714.29;seti@home,52333.33,367333.33;srbase,89666.67,896666.67;sztaki desktop grid,8320,41666.67;theskynet pogs,45500,409333.33;tn-grid,39500,514666.67;universe@home,47833.33,335333.33;vgtu project@home,20666.67,124000;world community grid,29166.67,263333.33;yafu,93000,838666.67;yoyo@home,7040,56333.33;NeuralNetwork,2000000,20000000;"; const std::string contract = "002a9d6f3832d0b0028606d907e09d97,1.25;002d383a19b63d698a3201793e7e3750,23.75;004167638daf46847501be39de7e941b,15;0,50;00565aba8b273e72f5292dd54c2e9d9c,40;0,50;007b76793e25af64dc29d68b5347ee7f,20;0,50;0097ab486cc2b1fb01e021880475c643,6.25;009b415d69801a2f9182069b9257f410,3.75;00bcd811d3f0ba9970189c7ffcb1f727,1.25;00d9943ffbcc671b79aec7d94a995bf7,3.75;00f6f068e6c7845b3433b6991980cc61,0;0,50;012bdc173281b093a4cd02543bcb52d2,12.5;0,50;014135e5cb2ebf8f283d1d1655151287,1.25;0,50;015baf274dd9265b1c53d6aa064cface,500;015bdd896fd7e0394d5148e93da2f7de,45;01656b71853d1d6b1a0f7e8795d1b9e8,3.75;0,50;0,50;0180d21299ca17267b6cf734c9d05884,510;019308d689c4253e8aea48522b9fa152,1.25;0,50;0,50;01a499929b07373568b3eea3b3afe75e,12.5;0,50;01d3236e6b82f009596aa791e805e363,0;01d77694989d3af771ee2c2bc3cdb41b,80;01df9a46fb210ed7b31222b386a0e97b,8.75;01f02f022cabcea12e899ce858d51b95,2.5;01f7a0f8b60fe3ebd799122ebe08043e,50;01f9b2b8cce2c8b3320d815303f47025,1.25;01fd21141ef10ad826c5b6d7d7a66629,405;0221c3feb81bf9e73d820036fbf02a96,1.25;0,50;0244d21e3dc2a743529f93b8dc3316d1,11.25;0249b19d285e6b0b6c7d255974aefed1,35;0252e7c76355a745a1f45c7b0ce56052,1.25;02615d216000305ab091eee9bc616596,0;026966c69d668fb625df0b9809725f6c,8.75;0,50;02c5e80c85f21c51808035782766bf5e,25;02cef20033aa7469d01768f7d0b187ff,1.25;02dab202fc1bc7b8ef61b4ecfccb0b38,1.25;02e08427b129719f838e775fc8be22a2,6.25;02e6d3a8e3e27f1a59cb3e878e91447c,0;0329499417b91f3bf4da6c6ea9a1fd4a,0;0343b16b6d8c24e0c098b88ddae39a2b,17.5;034685fbbaccefea46bbf6b7b1ca1e38,5;03579240e86ff48f2176cad62e2bfa87,15;0371fb3bb416365874cdd31b5795c88c,7.5;03735fd8066b71828aec7ce17196bbb8,10;0,50;0390450eff5f5cd6d7a7d95a6d898d8d,380;0391ab418c82b05f664677e48abc1431,1.25;0,50;03c54d4a58c58a9914f36d82e7525ae7,0;03d010e04bfa7db3852308300a800d94,60;03f0850806e44e8eba363a790659ee5b,0;04063bfc4e067c007fe3db1374768e27,1.25;041e0951f9c3ece0d0ba4d1293e40d2c,0;0,50;04595c27d2b65393a238509e074c0af6,1.25;0485d70830c06b568677a12780985949,0;0,50;049144b3fb2e414f5d122a2807066342,30;04a6fe7a851bcdcad7753ce170eecd3f,530;04cf70d914c9e8c816edeb04bb64324b,1.25;051ab27a3dc0a98cab388973e9063cf9,2.5;052456468d53290a0cdcc1dbde9181f7,3.75;0,50;05b2d0f351cd1814b238e16201077b42,0;0,50;05c21278af7999e749b1671ea90bc8f6,145;05d490b8097437b9d6c7d6367026c0e6,0;05dea7e23a009cf981933d090838ce22,190;0,50;0610f6d62e54d240fe0f839daad9b3f1,5;062c68c850bf90dd52f1d1aeff927d85,1.25;0639224a79ad5696557a66bd2cda41b4,1.25;0639771c67d7f228d327c2984b465560,3.75;0648646de5bd1f3523bc0d82561c730d,150;0,50;067bc227ca534998a56ec56c1f865e14,5;06b4562fecdba1ea9a774210ec7ce410,6.25;0,50;06c52d8ad2ce85b970137e39386cd4c4,0;06d27880de211dad1e38d69306598849,5;07065b315ac186d42fbe2e5ef734b7cb,20;0,50;0721d0b89f5af66c996932cf2e8ffc4a,0;07733c4b62bb81984fce796da92f0ad6,0;079f09b14b5a8bf3ae773340d9a54f82,2.5;07eddf7186858e6e44ba714cfad8578b,50;08321f22a670ce593f85cee0aceed378,1.25;0,50;0879a1c1019d04035193b8a2b948dcf5,5;087d11dd7e5b78fa3d3345e2819ebdb5,0;0,50;08af9c2edb34a9e4fefa9d0493fe522b,23.75;08faa06648215a402944e0d109a0e0d7,55;09163872b8088a4e9345adab66272304,2.5;091dffc765df88d341813c908b2b6062,3.75;091e576772dc5bae020f887c1f9fbfed,80;091e9ff7a5d9c34d4bb8b49e2bcb7bf8,1.25;093f34e6da5a3322b196d675243938f4,6.25;0953b57bdfb229d8a2cbb53c3bba78ca,5;0968f3f73c358da2dd8b4854e1ede35e,35;09696d66b271b84cfb2e7d2dfb1e044d,13.75;097c16fed6eba410219b5f52f954f5b0,1.25;09a99d4daf6801965cec61aa058c2062,1.25;09cb4cd605d6114265e185ca273123f9,10;09d2afaeb77938028de93d7e55844f55,0;0a187954d623c6bdd7799206d578935b,90;0,50;0a253e023f00417e3be21157c46a186c,1.25;0a2e83abb0b94b61a064ca4e693992ae,7.5;0a49adb03a2c93c914de7bfdf7ea1187,0;0a7f19e446a766dc045f7c39cebd508a,15;0a8d1a37461e99c2d61702857502493f,40;0aac95f4d6361b3a3bcf16eac5185a04,16.25;0ad644e2fee34d5e603d76c1678efb66,2.5;0ae6cb0c3b49ab3148f24dd890c76e12,100;0b3e9507b7e91d1ae13ca41262fee609,175;0b44c45c75607eee4c14cd71e9d7aeff,16.25;0b5ef259411ec18e8dac2be0b732fd23,80;0,50;0,50;0b994a7810d0dd2365e4cc898bb2f4c5,200;0bd0e69ef4973bdf9fed2cadb35815fe,1.25;0bf4d63e995d2b75d6b7d3d5b0fa9ac5,1.25;0c130640a79aab9f1eaed36277bc51fc,3480;0c214883c0b26b5ebfa4c9d5580b6f7c,10;0c795e2af37411d8c917822318408a46,16.25;0c7b77538a622713c80e7f8c686c02c9,1.25;0c8916c4698f55e64f2ebfdd8f0b06b2,1.25;0c99c1b399dc935978e2ad69b7f076da,100;0,50;0cd7082d3d231f5b24adc4843103f44a,65;0cec3b20e30830a7e44c38763e664987,95;0,50;0d018ee5353d349283563373d87ca680,45;0d213c18c51e00b5e76df2792f817f1c,0;0d25359c92b351cd3e7a60f79e9dd7d6,12.5;0d7bf78aeb1dae402525a417a38b07e4,25;0,50;0db1531f46733c6ef5e80fd6aeb9a9f6,18.75;0dc52ada952375686387379f3396a362,5;0de87e305d5d3a9cd58bde8a9f84339b,325;0ded68f4f2e69faf653e5ca9907038d2,10;0e2316e4045610d60c9d84531609a156,2.5;0e2ad09c8a0b450470825376aca24987,10;0,50;0,50;0e4f2209abcd450e225cee00a56202b0,3.75;0,50;0,50;0e807af5a446e8ad0e1339b00aed5736,45;0e8f88f0e8109cdce2b348c07226513c,12.5;0ea4ec2335db563b75502bfeaea14fa0,1.25;0ebe0b2cff3146a208f936db6315b6eb,7.5;0,50;0f4e985a4ce2a311305c6509f16b30a3,50;0,50;0,50;0f9d9d038186b9ce82514dd1379d739e,25;0fb5cfc30bb9db2a4a346c3a1c2c9265,35;0,50;0ff176f7197a0758474e945963658fb4,2.5;0,50;107c39e04551eacb5b6ed810bbc6688c,1.25;0,50;10d0bf50c237833b166ce6290bf25174,0;1100051546843b11d4839668ad177401,125;0,50;11320f149f742cef58a1bef1195b4929,95;11335e0fb00dbeb06bf66c8e66cb1187,55;0,50;114e1ae9cf888c85b84701192d4fad1e,11.25;0,50;119a55c3317899b497b7d86cdf77988f,35;11e1f64ea1ab2d83564092ba49716ecd,5;0,50;11e53adea833ab231cadf2c2d162a59d,0;0,50;11fe3060a2d3eab10a06a937e1474e65,3.75;1254e57ad28747acaf221aac75cbbab6,0;0,50;1271f88b8f79c4c372dd1afc26f54dbf,2.5;127c75f1c08d06a054465f4cdebe581e,50;128854b7416bbe0d2107322685109c05,1.25;0,50;12b2210c2ba27e94c7c6420de8d41adc,70;12d8c99e1b7623db14196bfb9bcc7347,45;13032e4da67d7c5bdde5304efd1b921e,2.5;130e72d20ec6c14a4505d9cc2f432621,0;131a0a4042a085d83d46d9b0834ac004,80;1324505e97cbe65de5f2cb3f44569c2e,6.25;0,50;132dcb97e51d4809e1ad584db82ca7e3,50;1338b4f18df53f80b8e33d6289e8773f,60;13509cf04f3fedceceab14ad52bf5202,12.5;138115988c79ac1a5beb17f45881450e,18.75;13ba18d2b5b412d81bd8b8fab698d469,95;13ecfb4e226e448b549a5e3e9a1c16d4,13.75;140afb12ef27afad8411efdc8f53c136,0;142b7ff9cf35ec96cf802a2aaf80d062,1.25;1440d0588d7308f10134070b9c7cefe9,5;0,50;0,50;0,50;147c97aa7263d84a8eeccf72f3e800d4,12.5;1491f90125ec87c45fbc34dbeab81f9f,1.25;0,50;14adbec6061584442558a2a371f34217,1.25;14d14af285d964807273d32fa10073f1,17.5;14e3c29cb30df696840e66b89d436348,0;0,50;152398a158dfd951cf2f87aedf1a4a3f,1.25;0,50;1546f3fecc085227b3eaaa87485c9c1d,23.75;154ee375de9d845455e79c94e1586f82,125;15547d60f7ba35f8e9c16033be0220f7,1.25;155824faf611f87e12a860041dfca1e0,13.75;157fd6f6689a119e3a1cedc3bdc43f62,1.25;15993c1611265079905df6671f80f3b9,5;0,50;15fabd8d529db1f16315736b890ce38c,7.5;0,50;160c911479d8f7a8dec5672bee25503e,18.75;16202e475dd85c0274a45d8ef66ff418,5;16343a0f41ad37bb35a80e81bc97ef8c,70;1638152dadcac51f8bb71da66dfe092d,35;16506698dbd1ca39557f63d50699ccd3,0;1665eb4e38141354cd5a9f786fc04074,20;167e1cb1e8ef1d3771ede0175e848120,55;16a4a513fbbb77b756173c6d1cf16b44,7.5;0,50;173c5239b3b3d305292f9c900abfbd08,45;17632277c6f8f92738ffbdbb647d78a3,2.5;176fe99aaccfb6a91b4a22e9ee5dc71d,1.25;17769e442b01f980d02cbab98b8688f2,305;0,50;17f5e7090a51b1bf7b995e624941e7bf,7.5;180d0f2fbafa0455b87ecca4607d76de,1.25;0,50;1835bd61fabf63ea2b89e463875ed864,1.25;0,50;1896495a2dec166ebcb01a525e90cb06,315;18b87714296fcc8bab47758ec4de65d5,1.25;18c25e9a719c92bedd77a3e1c5ac536d,0;18de9309ac296d9e636d53ab0a1b5984,2.5;18ead0dfd4e5856b28586eb3782c53bc,8.75;1904241f1f257b5ccf6a5f902ab9fe44,5;190f02ccf32879a29639c5c238ea6a6b,145;19114686c299710b11ceb2b467432e8d,25;193cd7c15933c9ca00ab79a9f92a54ed,7.5;0,50;194afc7d064db8c82dc1a32074aa41a9,1.25;1963a6f109ea770c195a0e1afacd2eba,180;0,50;198ad0b7a49b6382c6588b3a3ad3c388,6.25;19b71e4285fbf679e039c6fd5b85da0e,16.25;19c33cdfe8a965f8f09fc58410f7eb2d,5;19c7dcb3cd9b48d0f7d273fed58911f8,6.25;19fc87b4bf584c5171a1e94ec4ee3b1c,195;1a4cc27c96d37b72cceaff8b664e45c6,35;1a4e7f5d650ecd274e33d31df93f6441,40;1a8309fae79be20b42354b049e392fb3,45;1aa293f640ed36d9e95adea4eae46581,0;1aace2ce8237f2e1639abcdb93939dd4,220;1ac793c529cd6ffa942afaef7c5068c2,90;1ae78992d950eca9c475b87609506611,35;0,50;0,50;0,50;1b4c20cf1a314526b5305d3d9069b394,2.5;0,50;0,50;1bacdb252f5bef4427383960e930a361,0;0,50;1bd28d361cba26ef8f05e0e87ebc309f,15;1bdcc065bd6d5a89971c22682dfcc443,2.5;1beda463689f206361318f15462574e9,40;0,50;1cd3d44b18be07e4daf1aed496e23654,3.75;0,50;1ce3488a94b438352563639368e15aa7,6.25;0,50;1d1bc141a208135efb8c71c2018d22b7,0;1d453fb03ecd1542603bece39b076632,3.75;1db724c5bbdef33acfa16e037f113e6f,0;1de238ea03ddbef9fdeb868de4c74cce,7.5;1e0d69a04ab757dca00fe086328e0052,105;1e240363cbe48e99394365022b18a429,16.25;0,50;1e54c852d6f869898bd6e178455aab5b,2.5;0,50;0,50;1eab9d3439c2c7037600cd3eb3210c62,6.25;1f46c1aee0261e172fcaa2179fbc78f6,3.75;1f4d8215cdc884cc2eee7a7a29301cc2,8.75;1f61767caa1ec9988100c5f7b3d36cac,40;1f65951af61f337be04c8549d3d0e7df,1.25;1f76660396a6c85fff35b16ba550d85d,2.5;1f77bb11ecec1a449e616034c44c23da,65;1f81c925258a48abe4fae04920e6cc66,60;1fda325ff886a2bb0ed2a58eef458931,13.75;0,50;1ff457bcb9860833f66db19b48a3d9f4,10;2049f5c4c4f3412ea245eb54301c2a00,55;204d178f9b6d4de25297c99fed0ed860,5000;2082de95f77c4a69fc878de0bb3b2af5,3.75;209cf08ce2d60e836894ef4fb991ddc9,95;20d935529c2bb4c5cfc978f7a7ed722b,12.5;2103d322c0709aefd912ea4d99452b60,80;21099d58d550518bbaca6ad398fd36d4,2.5;210ac778c8ee55b3c1bb259e21c23a67,140;21184ba2719993e70d473e03feab9bf5,1.25;213692e90aaca3de6d2cab1c275a91b3,2.5;0,50;0,50;21cfd11edea6b24821b90f9c902aec00,1.25;21d2a18ac20936fbc86a9cb33b039da4,0;21fe409c1eca5d2e18338921d3bc823c,5;0,50;0,50;2272cd546b4c22257322839b6dca02ad,2.5;227487eeb096074d5bdd9d0e1852acfe,1.25;22758d57808f63ae2b38c8401fa3e598,0;22bdb49b05d620e1da710973ee76b3eb,7.5;0,50;2327f96c0a75870c2fd5e97ec5649c7a,21.25;232c33c207395fd98b1d5b0f31e435c3,2.5;233066a5b69a78fc637fca04eed48d6b,3.75;23a015fac33920274fc8309e422ad176,0;23c660ef6d2bc69479042200004a4d87,23.75;0,50;23f38656a95ed075ceec294708208c09,5;23fb46016e1456d99ac9101ba0d1d0d8,1.25;240a8d8616ebe69d5d906f7a3652bca0,23.75;2410128f88f95c088124eec27b8b94df,13.75;2418a181a8ce117c4d633dec892cf330,0;2419fb27eba52ae5972930cf1125e276,25;242466d114cc32914e02874e6226716e,18.75;2435f8ae46be67fa25b97d8dd31a9f0e,5;2455f1603c87d1590208c873f783b651,45;2462852f7ef0e4f00350dd1e44696a62,18.75;2481d123ae016fc584a99c01f04679c3,1.25;24d7526c82e4892dda4c567acfaebe9c,17.5;24e473df8c25c3f8cb8cd1a8a0e195b5,195;24e505bdf49d468bdcab62df799b5974,40;25030afe5a7ac52cf87c1e645ad402a6,1.25;25152782a45e060ef8f789a75b5a95e8,21.25;25247e504736d41b333535ad14deb150,105;252896af2561d8b7f3dea6f2e36061e9,0;2569d8ca4a6d4fded8091f85f2e3946d,145;2570e257d2bea64bc3695600f60d3337,2.5;259b837e185e461410bf4289ad7a0383,1.25;259bc772968e98921a87ea496cd74664,0;25a27c534282be4983e36ec1f6c6d686,3.75;25aa5533a8fab1e5bd4065a9eb815156,2.5;25ac460aa7ebe6800d67f4bbc9eb6fc9,0;0,50;25bd7ff42265d0b5b6edbfa79ba9e432,1.25;25c5be57374360c534ca9c2571556f8e,0;25d003249f8a48a462584bc4bf550e26,50;25e791a81c729433588d0dc076830d27,1.25;25ec44b1784ed33aacd252b285562a0e,35;0,50;2680890b90dbee2087ecccd16bb168f1,8.75;26a29ea0d4e0a74b4512b2306b35278c,60;0,50;26fc42c9167fae5ae43e4dca2978c5cd,0;271278273c16968a38b63085d0a9610f,0;2715d68fddd2dc2ac6a0151191dd9f12,3.75;271870e186c59eeb85f29c65888d4b54,35;2727abe80b9f206c143d8aad07beaf3b,195;272c3c7b15bd822930273742bca18fdc,1.25;27333d734a0ff6b674672870a8c86714,30;2739e10cc6acd5fcee74199f46428534,10;274f4aae5a3041085e95e9c6c0acc6fd,95;27841bacbf2ccdb70eeb13005ad18510,200;2799b8e961bcaefd31b7aaa0607cb2c4,1.25;27ba1686714e80a27e9a207d3a006c02,8.75;27d542179e931069dc31a42b0f512392,850;27ebd09fb3dcd68d60838ae3434d8710,20;0,50;0,50;2856d86897e43e601daeb1065983043b,3.75;2856e11490fbc63987ee0fb013421a03,2.5;285ff8d5014ef73cc83580338a9c0345,185;287f8c64c9903f49035fd16ba73dc4dc,22.5;28a5c23a1061697f57db1edd9ba4549a,40;28c530c5c941e0da1d8d98d2552dcce5,5;28e0ae8715768aff53e2dc971251402c,80;292c5e97f2c154175fe8100012a283cb,35;29492cde9f3bbb26fe05d7a68b55fe6e,0;295ca43168556f9fd96867c1e4b57992,22.5;2974e20c3a46c132156a13ed0e73eca4,30;2986d3e2497733ac3e4e95ef8d39af82,215;298becdd13b132064ce8e5da4c2e6ba8,3.75;298eb06debd588d27075b62804740a4c,1.25;2994c83ec2bcb7ad9bc01a5e60c96ace,1.25;29aa911ec147faa8927d15f0eaf57ecf,18.75;29b50891c25e1a2572409e32e3872945,1.25;0,50;29e886a19d116dc4f569348fbe5ff811,145;29f12dc6023619cab1c87f1f52914dfc,35;2a132eb110fc7d7c1d78cc957aaed5fe,1.25;2a258e2335606b01e3d8701ad7d63c5f,1.25;2a36939a9f3cff33952ed33dbdaeb8b7,17.5;0,50;2a567ce689d5f1a55c11578a8609a5d3,20;0,50;0,50;2a644edc7aa7b279c8216019f3a48f06,1.25;2aa2958642bc7b97af20113991e0fca6,6.25;2ab101368217b5888196d6a0e0cd61b2,0;2ab1d25870465d030757670a0a8dd6dc,40;2ac53ccd52c3655a8e15650ec02f9a35,0;2ad4194f66a90564cf26778ef29d8247,0;0,50;0,50;2b28dd6fd317650b0615ce4913d5bae9,520;2b33056dfbf5e5846964be10bfde6410,40;2b6b16e43e220ea6d4029a66db99eaad,1.25;0,50;2b815a31af79b825e13a0ebae2b388e5,17.5;0,50;2bccce355d5e0df9d7aefc38fc2705f3,95;2bebcc51ce6b307d8410ba59a9072039,480;2c4d9141c42abb1e9e465d806983ea5c,15;0,50;0,50;2c9bb1975c98529ef578649203a449ec,0;0,50;0,50;0,50;2cf3f182687e2eefe4103d7f2f8a373e,120;2d371a11f37f2035d26c6738ba64b947,40;2d37aba0d3decb72190c1053f29f7fc5,15;2d3c72a0cac1012c5a79cd3f3ef83bda,1.25;2d52efcce56e6d1ce19c0778f5e0d38b,23.75;2d7fcbb26dc2ea55502553a2d7e66186,6.25;2d8398cb34871cd48f3281ca1b69c93b,18.75;2d970fb5b1c4c346876cfa0bffa73980,50;2dd690ee460688c7c2fb5ae622a50ee5,25;2e2d8005f09feef6ecd400aedfd9cf82,2.5;2e4b006f0687c93d606e92fcaf79fc7d,5;0,50;2e79d8f6d3f3623b31ebed0f14343607,85;0,50;2eac618ae38dde417921473f8f54dc8c,65;0,50;2efb03ff67b254f248859b9a5b091c34,17.5;2efc564232f2ac881bf992a6d8b4a3d7,23.75;2f3220ad96ba1867267252269f5829ad,8.75;2f466f1422af73eb806fe3c610fc042d,0;2f65ba5e9fc96e0a0c89bfd5541e1e72,0;2f77f764c4a31e7f29e7be78c9fb3caf,1.25;0,50;2fa5216607ecda3cfb99050e305ceb4f,310;2fb13153ba7699f46e2bd91ddae5bc1f,23.75;0,50;2fc4ada00afb3d2ff1337c1a7e502cb2,6.25;2fcaf5ae175f8b604fdf344b1d970092,70;301284bf125237fe3ecce2e2d04c3d08,1.25;0,50;302d89b28edc27fd02fabace737a1bab,1.25;30371bd00196619853782bbf95df2880,75;304db089b39fb4b8693011ec76d25444,15;306843250cc1a70f0a83ca5f63d58eac,22.5;307dfa258688c9274d18906cdf22a957,30;307f6656d708c429a6c4174114fc834d,30;3081ff717f5e91cd0b47da5349bda89d,85;3088501f0ab8b252e5c3069651adf4e7,0;309a1bd57a746241e8b04f39c38d118d,3.75;30a22b44c728edfa83a39d2a709dbbe1,16.25;30a488fceee8c0fe54aa1346dc3a65b8,18.75;0,50;3100545d0b7e0923ddecfe509dc0dcbc,0;3106920846ead813a9b0cea0b69fd78c,10;0,50;0,50;318fc669cdff43f60b67fd5f7791651a,3.75;0,50;31964de0208072ab3868ee960e0db9bf,3.75;31a6a25545803fe2a413486ed032064d,0;31b166561cb4639e816561ef7a5f25d1,190;0,50;31d4d989f5f68c1d70b4a8e757dc08ad,55;31e90abd9305b166bff3d853f907e9e4,10;0,50;323784b475857b837b4980235e1250b5,2.5;3238ed33fd0ce096016a82a60343a2ef,11.25;0,50;0,50;32b4c6a08f16882ff70fc2eac56e8a73,40;32c06cc23ec1d940d9ca336971a7023f,5;32c10dd4484fc66109cf48bbc490e60f,2.5;32ca74dd9b5a1dff5dba9c277165f3ce,3.75;32deab6b034ad796bc9537580f7c16d2,16.25;32ee2ae7b68222ff8cc83b39a35d52d4,35;3300439bdaa7574d5958b8bda0c34299,5;0,50;33a59ab3fe8c1ca266ae6e58bd106f0c,17.5;33b999143e4108d2a641b03642814f64,12.5;0,50;3400232bba3d404ab2cd4f2375a2cff2,12.5;3428674e02dd97b2a07644f0cb785e75,1.25;0,50;3448c9b19c775b70d4a86bae6d0b72d0,45;347cc1581e31f5864a072e3d6fb92158,80;34a52f045ef95cfc78cf4e38d54ec2a3,175;0,50;34d68eb799e5dc39b66b160b6da29e19,1.25;34dfd33b5dc960c4f92e346efc79e025,6.25;0,50;34f3d247ace7b0d490a4ddc04db1198e,1.25;35163d75e76fa7fe55b69b0a3b6dde48,3.75;352d0a5d4e3b8ee1f4f73a392604b4b7,2.5;3534084dfa6900327f3246cd71bf9edc,0;0,50;3551328c7020d2916a70cfbe0e4e04dc,1.25;358a2a738169a72a484f888a90e309b1,12.5;3599e778dc0573b2dc8b7adb21dd9125,1.25;3612c389e49c7d8aabeb65f94dccc481,1.25;36130b8ca3b36b521cd663e4f203b220,13.75;0,50;362f13fb407f2b3b31e598d990084f34,1.25;363d6c820aef2dbbe082768b40feed0d,25;3640e93d6f77334e6a153ef42e62c1f2,16.25;36426c381e65c5e28ba4a1dda2ddc692,17.5;365fa3000d8605751fa26986a07312ce,0;36767dd97caab66260f85bcdc5fcaded,1.25;367bf9bf7fa8dcbff2a2aa5c8a15c276,11.25;3693f209016eb19127d44dd37598a099,0;3694d613c5b724111186b9b5e1c90987,6.25;36b2e0bc19926a7b4ebe5f8556bfdc3e,1.25;36c97b76a5b7cc67a9811238d7c8d2fe,70;36f64d69eb8c5ee9cd24178b589af83f,00;0,50;3724f4f178b5900b8d2ef459c9c6390c,21.25;3753a6168b202703f3a7c8ecbd122302,1.25;37659f81856e2b5a593b6b8260496121,0;0,50;37740fe65e722d7f644baaa0900a31c3,35;37a2bbd4eab5f01826896485f6f85d89,21.25;37b273e5d905dcbc318dd7c26f4f6d4c,20;37d04a47c7e73ea910ddfa345991235a,20;37e00dc9652d8fb9c8f46c0154c48416,5;380348beb7eaf2cba4ce3ff4ac3dfa89,65;3829e8f8d114cdf32d5930a9efe8a011,2.5;384b5a0dfa52458a6e30ea4b40100b24,0;3892d0b1db95185b2d0ea34ad5bb2bce,1.25;0,50;38d5f74909eb2b79691c74cb023dc16f,70;38fde78a0f3f721e2453cecf91111a22,18.75;0,50;392adbefe3921e9fc8162c8b448455c7,16.25;393491f5de9b4ef0d350fd9127fadee3,0;393fbb53a3dcf6008653fbbf9b25b761,16.25;39578e45afbf5e766bea49971d8a3d56,35;39653bd4d97c4cc0dc91a06576ea9af8,6.25;39a90afd323780231512067002170b6c,1.25;39ac616c742eacd2acd078ff4516b652,35;39c23f6508a379eb52a0a146386ae67a,2.5;39c39cd511790febde28bb8f5bd16279,0;39cd843c432959c0cf9d5455b820b040,445;39d042f5bf38eea042a1df3fec390b7f,10;39d643f22e6370f295795cc67d779c93,50;0,50;0,50;3a0941c1ca14936c39bbe9241fab7b58,50;3a11965fc943da0d7728f28097e8ac41,1.25;3a173da0c03a1bf012dc204c54780ef7,1.25;3a33d814b1b9cf0f0a65ec0356f62a01,260;0,50;0,50;3a9e4fef5aab78f76001fc0e81add764,1.25;3aa3516cf3b19b343ae7c164fec56916,18.75;3af3d5f002af7df66239b05a0fb2f970,1.25;0,50;3b0fe8ac97b440033199977033b361cd,0;3b201d6dd5645f3352f30cc0ae492cc9,1.25;3b3faf83b8d631ce312eeaedecd761b5,720;3b506ca17b3c9fba239d8059ca4846cf,2.5;3b6a56ec59eccff260f947784b4a0f36,10;3b6dc2071547081fde8af9364f760c37,8.75;3b9cdb1064deae88b839bf167d54eb70,175;3ba078be03af543a54eea1c10812a716,1.25;3bdf7327af96b785a14edb7a0f4c7ad3,5;3c077620e211d1237d796b34fe93941d,120;0,50;0,50;0,50;3cbdd3479037671b3575eb6fefc7e79f,2.5;0,50;0,50;3d66e11ed9b5f2b2560831c86cb2a5e8,380;3d94db00b3c9b28e73d8b5ca5cbed4f1,25;3dac7817b15509f9bc6df536cb71c28e,40;3df6e3662e9fb9653957f8c0866c4e0e,30;3e05fa9a177a8c8ef4b1b03207393dd2,30;0,50;3e28e6a8b460b46091b3085abdc8dba5,1.25;0,50;3e4e5ee66e0105c11dff0eed0519cf2f,40;3e667635d8564358c1df28d43446f6b6,225;3e6c0860144da2369c0fc2c8e37f4ca2,55;3e83d0bdcad30a98acb020a700f02ccc,115;3eb05a28373fec3f42f509d5054de10f,2.5;0,50;0,50;3f3d11a5c0b5ad2ce388caa7b6bd8cfa,5;3f6b519a871e698973d52a71deb53236,1.25;3fb01ffdd5f274efa8d068ff9244abd4,45;3ffc41d0451611709d345fc7524d837f,50;4018f7c1757226f9ed243b4d5576ee44,17.5;0,50;406c50e3243d7bae9b6d67e732f2ec9f,90;4077daa237c6a89b1de46427ba6aeea3,0;0,50;410ade0b286579083b52fcf2d4f8fa2e,11.25;411567587e0d91da48f891aef5b1e218,50;41261836240e4689f414b6ad927cb4b9,15;4127b74138df74bd736ff028d73cd6d6,0;4144dfb8fb11cf3b2aef513ce71ec61f,1.25;416e6717466aefd2f3ffb768ed37b38f,140;0,50;41d9c0a351df384e2151b8b6184a9089,1.25;0,50;41e34ce4554d0e4bb627649a215f0bbd,45;41f3cf3ece029a034884701ada7bf08b,85;41f74199e5d4bebc6feb7d225507c2c8,21.25;0,50;4217ad404b141716d5a62c6310c4962d,23.75;424391861576ab2cacc55ac5a720bee7,1.25;42507db3cc979a8da12cc68b6d87fb6f,0;4255bf7a07011016e9152f2cba514f6e,90;42754bd93b87913ce07affcf6f903a06,1.25;0,50;42da2ff96627dbdbeba12f5086a425e6,1.25;43146963e7d4dd01e5a4484f512d5caf,1.25;431d0ac8a393f828adc516d173553434,60;437647201dc201f215392cf92d5322ca,1.25;43976f32f82d1a2e917a4357c4e62ebd,55;0,50;0,50;43ba1b6cfd38c2dd0128dbe434310c52,0;43cc6d22950614e3d7f2873c2acd4fd0,6.25;43e87b406ac2cfe501dfbee3c7745ed2,1.25;43e8f9f4f9bcb4960886d949a6b3c4cb,1.25;43eb836a309e2fdd687c9aeb7b04eef8,5;44171557b5c9afd6271e52ac0e0393ee,110;44234729d08b5cc425d416c0a80f010e,25;44787e32b6ecb2b1a3e0db42cc1f5355,100;44814e2a5b987017d5746d28428a1825,18.75;4496ef44962d8816175b90c4b2ae7d07,3.75;44b370244b758a353bd601852a253812,15;44ba010b758be714b1d31c1fbc1c37aa,15;44f3310db6eebb4d478dd8499cd414ce,10;0,50;44fdcbdeabc3343e9423421cc96c6187,0;0,50;452606c09e62efc8df6c6b1561bbd1ad,1.25;45272229fb8fca150b3af5136f4799dd,100;0,50;45450db757625badc83bb0986a5a05ff,0;0,50;4563338e20bb2bc44d6ea9dc28bb70f9,8.75;457e8dc224c7e5bc9e56e0ca4015e257,22.5;459c370be585239e8bd677a0d17a265d,0;45d2cfa253ae0bd3bcc13ac60ef3ca57,50;45d41a9a72999e2097d5aa194dcac9ea,3.75;0,50;45f0b18d3abcb35452bfc7fe7a978c8b,2.5;45f5f8d682d68e235e8aa5ba56e5d2c3,1.25;46023cf1e7e2e696cf3e550eb9d74dd6,1.25;460666688f54d04f41722588a206f86f,1.25;461a64d15831e30612ef9ae342e8038d,2.5;0,50;0,50;46e35c04a2e1132c063c45fc10d06674,1.25;46eaa0325363106fcd97b35be9a5c24a,150;46f64d69eb8c5ee9cd24178b589af83f,5;46f6da7497720933204d7cc478619bb8,1080;0,50;46f9e92558d4767e9dce02c5306a7ec0,2.5;47169107c091ec1cdc3289f49a1accf4,240;0,50;4764e459792d9b54b62908a5124620f8,5;0,50;0,50;484ac11aa23e0d1eb96ab077c93b5ee8,50;486fdb05d259bc55b1ee50ee507242f3,0;48702ff7e416d3f0f65a3b2af2bf25dc,6.25;487d53482e041390b3f2ef8112c39530,0;48afaa2603f2c2a285cadcdfdea800bd,3.75;48b36e89a248e864fcf92b537791edca,135;0,50;48d7a3715f2f60bf16184d10dc3edf1d,3.75;0,50;0,50;493838c5c174166fc5419268f5fce98c,1.25;0,50;0,50;495f744294b3df685da28664985402bb,1.25;49825c10de10c5b2556a7cdcd161a868,0;498cd0cce160c06b0efa52064e96531a,1.25;49970b82be2fc6d67ab78c3060e3485c,8.75;49f165229569bc8e7e49817686f8e23f,800;49f5d6ae6795dc13de42bc56af591a42,5;4a2761a1a29ca83444d5ed1f6f641ebb,35;4a46f179a9db63cee678c988a3aa8741,12.5;4a5176e4703036c98acf2d3f51e9ad9d,23.75;0,50;4a7d815d29be5adc1b7052f465f0d1ea,220;4a872317342ec4c7bbe6619b22e349d2,1.25;0,50;4a9dc577aa0090fe4a68f558fb7e3837,1.25;4aa74e11f2ab67766de8475593c2def3,0;4accec0414fe511392afa9ba6874d78a,30;4b0d96e39429bafc65bd1d3a8dfcd8eb,3.75;0,50;4bb728c90b20abafc3e935644f421b60,6.25;4bccc9ed9fc8cd1a25c92313818b68c0,1.25;4bd3bc6ec82e30a222ef8d1bf2991d74,1.25;4c0cfa75a878afb61662b48c409b2386,55;0,50;4c16785dbae7703d3c286f5dd9c54020,45;0,50;4c27f4e2cf2979c3ff38ac544c2733c4,1.25;4c5a8d63d604df29f09f15714680925b,22.5;4c76488684094b9d5292b5353aa23fe5,2.5;0,50;4ccb5d307a952c3d06601081fa060d61,1.25;4cfd748c900d1baccfd304fa53777bbb,22.5;4d6479748f61c6155e1f6e1122b744fa,0;4d69be38d1ee1cda339425600732f38c,1.25;0,50;4d9411a312fc384a6206ed46b671f9ce,5;4da3743bb4071d6cc28bd862d7ca99ff,21.25;4df3a46d36df6e1a85bf5e6fa7681172,0;4e3151afbca820260ace7e35daaff697,1.25;4e579cd323d5c2b17c46accaabc60778,0;4e795eb72fed0e42030bc9549877d03b,0;4eda14a2be77e7d16c988d56adee4af9,85;4efcd623ebb1d1280f4bde8081b886d7,1.25;4f0fecd04be3a74c46aa9678f780d028,65;0,50;4f302e181503bc27c4b87b8507be0985,22.5;0,50;4f4c22865751a0ddec009df96db4c9ae,375;4f547570c2b323e3de3a390851dc5c0c,1.25;4f6d7b15b4ffbcba3f5613a426bb842c,1.25;4fc1da2f1721aa364e50ad3d57bc739a,1.25;500f87547f2a23f8306918f803247d5f,0;50178bea882248e42e77d0a0d4b412a2,5;0,50;50b175ff128bbe6fe422c1e9bd60551a,10;50c49c94c2d3e43657eedf009e48c5a4,30;50ca7add82b7b1757f6027a2aa33a1dc,50;50d9f166778f02bf30ac3a60f3701e19,6.25;0,50;0,50;5137bfcb88c71f5e40f83d71f1d8568f,1.25;513af4784ff3a8a432ed01978fcf8239,1.25;0,50;517217f1339bcd695a27813b0e3863a9,15;0,50;5188365b01e83b3244477e8c9a0062f7,7.5;518b20dcc7217d02bb484d7e24015266,12.5;5195ed3dbae78ce7f33308667c18d212,1.25;5197047ee3ab232f6d1b99ce8003963a,45;519aefd65f7c273f57c2d914053be96f,22.5;0,50;0,50;51cc91f4d02b12eaf1a772c3fe7bb414,1.25;5218e40846677629225f0c6bd5fdf428,55;523e8153b2c6f5a6af457043f681e2c7,23.75;0,50;52987d1393808fffee993135ab177d02,175;52b4b14c1772781151a80edde9d3be34,45;52f18e715ea68c15273efd226018dab1,0;5327a1d7305c86a4fb2df34649e70295,1.25;533d678f9f1fd118f45cae2ad3439654,5;0,50;534137c388453a2de05a1ba3c8e30d94,25;535fb1c4d3230305a57a95d94902f58f,5;536fcb1f96d4c755f4bc6515b0e6ea23,15;53849d520b59553a530aaf21cc645a83,2.5;0,50;53907566099fb7fd9b9085f80f21b5a6,65;0,50;0,50;54404c886a6a3ffe385d86326de7a75c,7.5;544ab3aecaaebae3884354adb7348b6d,0;54a4977f7458383527e7082ea757748e,5;0,50;54b6924f9d2354c2434b414c30a8583d,0;54b70986cfe93a59dabfcda63d3fb522,1.25;5506f0410b754e98191ada888423b4e3,3.75;55082521e5781c6cc91aa6e2560f3338,1.25;555a433dfa6a3da4370785bdfffac3e2,8.75;556aa48600aa6a423dc2a7dc9058f0af,105;5579559927de2ca1b5e73c6c9eb7408d,0;557f16594dbbe040d13155009e949783,6.25;558c3e1d4623b1b03396a066f94d9cbe,2.5;559a8c195773bfbe89154a3da0c7d13b,40;55a0cb448335518eb401631a8c31de48,285;0,50;0,50;0,50;0,50;55cd02be28521073d367f7ca38615682,255;55d5bff8d4a1f038692788cff11fc400,8.75;0,50;0,50;563266a68be74bc9edbaf1fe8304c8f3,30;564095cc8d2bbf62a4cdd39c1b077e39,65;0,50;5693d396fb5e03f2f569b0811bba5e85,0;0,50;0,50;56becdbdfb605731c2a07f2f0d892859,1240;56e40536828e7948eff5c8c1c65f0fee,25;56ee064cad337355d0d09d3c74cada96,11.25;57082f1077615cb9bbdfe155fb08c16d,1.25;57297e64913d406ce935515010799ec2,20;575d3a53f4ab77448fae6aa5f8f5bdbc,13.75;5768fceb3426bc016c86ad5d2e16ae3c,75;5776d1ccf8a3ccec8a382e92044e488b,35;5786fd54a1e774eff07735d52bd8e82e,45;57bfe70f547c240206ce62be4406bd8d,25;57c248907745534871b376443c21f5af,1.25;0,50;57fb94b1015f257feb539d36cb65540f,120;57fd619ec54f1cf934abdb717eddb725,40;58128a04acbd05ca44a50cc381b2665e,85;5814bf6781118f862b33844b6955fcc7,0;582456c223dab39e31167a05a59d77cc,3.75;5831ce2aaafac8b2afdca3226eb3f2dd,18.75;0,50;587d4e79693da1de3618fbc85e13dd6d,85;588caa233f04012e46fb194dc5242655,1.25;0,50;58a91bd739c216c35ba9ad5ac2e4a1cf,1.25;58ba3afd5b36c5db26bbf832a403e75d,15;58e4c0f27f7ca8bb6238f5e7b1f23ed0,365;58e565221db80d168621187c36c26c3e,2.5;58f338e522e87352db4aadf783022271,16.25;58f5b01c2a4356551bb9c770f2ce84b6,6.25;590ebad6f7c8b96305c02b7ae3118ca5,40;59126111e2185f364a579902ddd90a99,2.5;591d97a90ae4828ccefc9609b57704f8,45;596ed713f923e45deecd99098b507bd0,5;59900fe7ef44fe33aa2afdf98301ec1c,90;59a90501bf45a4f796c20553e12edb73,0;59d6620d9e6ed26d6225ee21c295450a,8.75;0,50;59dc360421f35ee08c303a1356ba971f,0;5a094d7d93f6d6370e78a2ac8c008407,120;5a27286ff16139609f41c007a98956c0,11.25;5a4f5fe06889a90d19f21ffefed270ba,1.25;5a5dcf06ecb928541d67adf68b19afc8,105;5a95f32b7f396a65cdece7611e22f681,6.25;5a9d423f1cacb19732bd78b40320907e,1.25;5abd35188c984cc0089e301b84be447f,0;5ac095c8797acad6acece5321e51f069,400;5ada2d8c7de68b7bd0bc8ac79968d96b,1.25;5b1b598981fb635791d6a5a0326d5703,1.25;5b82b88264a022827fc93eccc13f21cf,2.5;5b9ddc09d04112f3d861a65638230e40,13.75;0,50;5bc29463f687174eb5ccfdd91a7f4f43,1.25;0,50;0,50;5bde9859c50b6648f44ffbfd4e43ae5e,65;5bf08fe0c18c25c1542170d3d709f465,50;0,50;5c215dfd464ad07701a001e30bac678d,10;5c29a2f4b123bc352a11425cd584c08a,115;0,50;0,50;5c570dbf92054653ccf2d460cca0773a,1.25;5c5757cf8bbaff760a018c0e7d3cd358,45;5c5a0ac93fc004296d19101970598527,75;5c7c2a4ef583f8ea2b7e6e93c7d6b091,1.25;0,50;5c7d113191d667010aa6ce3371559a26,6.25;5cc68d90e0f41da83433a369452d7269,1.25;5d0289c6a9a4b1807bfde5006dccf1a8,1.25;5d08458b427742d5cb90bfc80cf8acca,50;0,50;5d461077eb1ccea5211e02a7c52194cf,90;0,50;0,50;5d5fa22b9962c43778ab1b898fcc0ca0,240;5d69de358e4826b5b8ca94aa759636d3,21.25;5db5009377f6230e7ae6810098bdeb64,150;5dcc2cda74bbec9addeb5ab85b19486c,3.75;0,50;5dfeb00f31d1dc66c4ae41769fa5a414,1.25;5e0e4f11b543f6305f3dff19e75b37ad,3.75;0,50;5e2643eaaf756261c14266b20615164d,2.5;0,50;0,50;0,50;5e741cbf121f50b8d900c0dfbd91b9d2,1.25;5ea36f22b19ffa435272df2a3085d78e,0;0,50;0,50;5eefb36471e96bdb379070069d33b8f0,225;0,50;5f206f44f5ac5b8d3871069ba35d0a3c,0;5f4943990a0fe0ee58465d521f2caae3,0;5f72c050e6113cfbfcc964bd5eddd359,7.5;5f86a117e72894aef2fec9066a04f80a,0;0,50;5fa2aca455267a1ca8d963624db3f779,1.25;5fafbe6930402bb3d4a46897287ab2c3,200;5fbb6520a83d78819f7fb0c9796fe042,245;5fbdb4cf93267901387eac47b826d9c0,185;5fcf7db537e9d862a6818adce1963cf9,0;0,50;5fde3a3d059f8f9a83e0b4bee880877b,25;0,50;60329cce9f0f9a36b4cc200ce9cb0162,35;603f1a690bd76ad283d67480e011cec8,11.25;0,50;0,50;606310ff4d319789a4acbc6e36334390,7.5;6065aaac6cd4802993fa634eb6d5fa4c,11.25;0,50;607a6b0c183392c35122102685db312b,1.25;6081597053addf38a34795d9b052331f,11.25;60c4c00efbdcc488e1246616428af665,0;610a567aeeab933902544fe36a1f46ae,1.25;6110dcd20dd010307cfbbd92e17c5142,22.5;0,50;61352139ef237d88badcab4f247dbb16,25;6139177909af1e2fe15dc658dfba058f,30;613d48a44ca2498fa2c7eb65e7120839,0;61805f016f1cdf5cbde9b7c3db811c61,7.5;61adb1289f389e715c1146216d4906aa,3.75;61bf4a1cb19b0fe376e4ac82157c39e6,3.75;61d48c317d3978c522c7eae8111730c7,145;61d65a5b31d2e0a5125b02205b7a492e,1.25;0,50;0,50;621fb15416b7a0ae68639ed91a2ebfa3,21.25;622d5b5ccb41254d2fbe051a677069d4,0;624af997f36b7c49d10abcf04bab2368,10;6298ea8e38d9f12757ac42df1014fed3,0;62d367802532c6c02439f506d19d8b6c,70;0,50;631804c06166c3b1390edf73f477d262,40;632b1d5280af4929fab92eee6ed1d920,15;6345334aa56a45222a62e9b99d5677c5,0;635c4bdbcaaf17c29b04b5fa786dd5de,6.25;0,50;0,50;6387eda1469f5c8f07bfd57eec3b16df,13.75;63b06dd944e9daa751006df3e560d030,2.5;63b747c3f2f61e55ddf5e041fc4c9a05,1.25;63d16f6259f4af0df85bb60629c86e9a,40;63fee39e1538c86df43ec41f98f26dd1,23.75;641eda1f32141ca9e574dc29718f7306,1.25;64200123ce5c8fe449b1f89f5ebcf87c,16.25;642964c79125b793fae14c0844fa701d,3.75;64296ed86ba4f1d1445d0b44da841f78,1.25;648e5f9733ef00cc3a44718b488ee799,0;0,50;64c2f22136127a6c2f77ba038c9dcd6c,25;64f50cb82800863a7f5f316324d01194,5;64fbb3689af59bf54950dc02fab5334d,2.5;6505bffb3eafae71310c39764f61774f,8.75;0,50;652147ab9316678729f6175bf241de02,0;6522503eb91580a36e878052567fd992,11.25;655d5e4a82660e0e2adff3c50675a14c,3.75;656907c542a0d1222101637421dbb40b,18.75;6584831f31981b81d8d22b2add556335,50;6586c7a2c89cd73abb1fe37d2240a80c,3.75;6587b0c61624d2b891fd4818e9d539ec,0;0,50;0,50;65a04e48495e839db4645eb74ba304e2,70;65a9035202fbd0c2dfa18453ceb30697,2.5;65ab42c37a94e9bd3869dd52d50ac7a1,2.5;0,50;660f1cb267485ad903ed8ca856bc8d8a,50;661acb02264b8d5c129fa3c5103b52fb,16.25;0,50;0,50;663fe6b7010ad83e4d056f00629df188,30;664ed3f4be02dbdf1dea36ef61e4c66f,35;66811aa73faf0dedfc6419e44172fb2a,6.25;6681e555cc423b63c6069f9e217da908,0;66b46ec70995f5586399f05216a3584b,0;66b72253e65aa9eb2fa66b7a948870df,20;66bb7f7188387b79f506f56942cbe5df,1.25;66e2778644bd2274c93102034ac92b24,3.75;0,50;6722b590f36a7121acd3a441ebc9bd2e,2.5;0,50;6793a15a9306ac44277737793b700d86,0;0,50;67b0f504a77b3f91429844591b1bbc2b,22.5;67b6ea3ddf94791ae5fb84b575c881c1,30;0,50;67fb34fae9fb3b092b031f3455c76847,0;68210327c48aa6c4b4e01eac42669d3b,6.25;686ad2936dc628febd74dc850a749835,0;0,50;6885c14cf468a9a7ca0d2610d2850849,0;688c698ac5bcfdd3c1c3098eb692ca32,1.25;6895f303968ae1ccd62e2b174739cd00,22.5;0,50;68e989f93860ca8393a464f0a095fe73,90;68eba0780732e1ab547caa888c2f3431,35;6906dbdad1b388ca39fa23be405687b1,45;0,50;0,50;6948e77a33fceb2cef51184fd480e5b1,165;69965b6c42f92de559d9766e2e8a9700,6.25;69ce829f660e550a75876ca3b704d1b1,1.25;6a131afebb1c7dd718001e77c14dd230,30;6a151dc81304be1c02435fcd067ce668,35;6a1968d4ceced2dbbd41d49b2402f9e9,30;6a1d0093dfc3116f3e860546f6e004ad,16.25;6a1e991f1416340a215a2f51e8323d0f,6.25;0,50;6a29545cd953d368ea6a2277f2985797,3.75;0,50;0,50;6a493af41a5c8370045e1b432e893145,0;6a8115a8a756e33f62d8e21ae95e8095,7.5;6a8aa5343a6cd1cd0697da5a444eeec8,7.5;6ace0fa3c8072d52af486e4769a8863c,5;0,50;6ad54a9f1c4d97c9f1857b31c6a4127c,2.5;6ae1bd193688a5b37f30bc3ca18a4b94,0;6b053c9c7d2dae33ad868c41e2779286,0;6b075145fca06c9f0ddce6df72331be0,45;6b138cd8dbea4438e1dcc3c044d4208c,2.5;6b1d56acbb46d2def060db99fec4f36c,25;6b27e18f2bbe08d98542351109c9da69,1.25;6b4b847528e3c21caadfd1459aaf9eff,3.75;6b5280410f95f0ae72f5b4c5164d9a0b,1.25;6b676026e41d58a9e05f0428166a22d2,35;6b778f9d4e8cecd3b9b8ce392949946a,300;6b886355089fec17ed4bdd1dd77d7fd1,50;6b93486f318208cd2c41106ec06fa5e3,2.5;6bb454bb70d0512a87276648c63ab92c,0;6c202a503c69a729d876990f5c563510,1.25;6c3902c92a7dc57c304c4208de952d23,185;0,50;0,50;6c78cc1b72e28daaba8d03cca3b3eeb3,1.25;6cfc87ffa9dbe03cd875519a3b22c8f3,45;6d0858d2315c2c3a7afbb80bf506af7c,16.25;0,50;0,50;6d62180c99b98fec91c98eb0160cf843,35;6d9999360dac7d871a242a18a649d7da,16.25;6db50b1e28f7f2d2420d3a96d9c73de2,165;0,50;6e22d722d4f2a68b69b1de8bae5a92f3,6.25;6e6e677dedd9e7d963f3036a6909854f,2.5;6e78106831ab0ff94589bebe9aaac661,0;0,50;6eaceb05c6f402c7b9bfc4f5e5f0bafd,22.5;0,50;0,50;6f3f5c0d930dad38776fb3b55c328c52,0;6f4d373809620f9e515deac5d1570a38,30;6f4dc5b48ec0104dca18d50ceb483fce,70;6fa8135e25b9e32432dc3394dcdebfb8,0;6fafc54550ec87d1366a7fe550f4100e,1.25;6fbbbe52d64484642c2c7c1391a1173f,30;6fbd4ee33b849c4984ce508772a3aa44,30;6fbf64ba5ac7bc486cc7a9b1599cbee8,35;6fdef419a9d36926fd707131a7fd7e53,1.25;6fe6f18a943659ad768f83556a2637af,8.75;6fef768a3a12d4fbbf71293346bb3fa2,60;70037377bd15b64f35b09c6d2d16e093,45;70101227944feb1c123e680507e032a7,8.75;7017451628abfb338d625317d6573374,60;0,50;7021da658effc8257e6c7d548ab5f85d,3.75;704111d3ea3e0edc73176bc1c15ff02e,0;705055dd4d71d2b56109235b0092ccfa,2.5;707135366333d87d602449754638c691,6.25;70748579e6a56dcb1519f81fedae298e,22.5;7078b7e5ecbf56d860f21a62f107b63a,11.25;707e43d51e302fae085b4a2a8e61f964,18.75;7092e0a5cb6a2137b9493b540610a791,1.25;0,50;709dddd8d73e15bae7e72bf1ebe45570,1.25;70af88747de330d2f82c3d97e9954d5d,0;70b4c3e128808d7b2558fe30fe36a5a7,16.25;0,50;710e8ae0644134096d0b8896d1f22319,0;711b7a66a69cc0a199f6a8685f1bd2ca,20;7122bc6cf04c46488c8a72f205995dd3,30;7125c79acf0970533f7bdbbbb6b6ad4a,65;0,50;0,50;71bd1d426829c297065d9f89a1a4c54a,8.75;71c3678da972f0aa70a913f0cd2992c8,0;0,50;71e89425d98117eba0b2e86a5e517803,90;0,50;0,50;7223e6551a9df0b14e6ebcb991375736,30;72298acdf7f6a23a801a94d5886d666d,1200;72577fdbd28a8df77b6b94e9c6ea226c,8.75;0,50;725b0f449e07f3fca83f2e4077c254a3,0;7262a5bb0696362a2a81e4f42a5c4c65,23.75;727aa043ebcd8eff51af41145cde178a,1.25;727f64f317c5de1446a67aab8e613b12,2.5;72b823c364e92081f0dbf48b954984ad,0;72e9ab7d146741fa721798b5af7f8306,1.25;72f67a25ad2dc9e76d746c5b04b2d49f,0;0,50;73461d3d3a5bfe972b9328a202c6b794,35;0,50;73510d2e73dc738bfc369ede1395e26d,17.5;736337c40f279a4eb1b0cd2e52d51e81,125;0,50;7381178f675b3e95222cb91067819a6e,50;738d1fc87e2ea866d98ae4266417cdd9,45;73ad01ad1684fc2be1b231563c5c5476,5;0,50;0,50;73e059a367496491b62d3a9e5f5867f1,80;0,50;7405df90cf38e7f7ee1b38a6990a809a,40;0,50;7467b330fd6b1f14d368503a950a7082,3.75;74a5319a4ff7a6b5b392886ec38a188b,1.25;74d182ef76759c42aff1b0c5bd879abc,1.25;74dfe1aa2995bf42676aa43f4478e101,30;0,50;752bbb4e0821d53e1e29e78602b72f3a,190;755be60e1ff4e40e747a6bd1ffe3ff49,55;756f4ee619de3d57ae3c9eeb44886926,25;0,50;757b02cee20ff252bcc5df3fb8f74088,130;75aa5b78345db2418e611e03580fc1f4,25;0,50;75de206305693b235a3ea07e1fa3103c,23.75;76256e0658aefe12372fa0efc3164c58,0;765643d898f921eac4ded58b89480cf8,0;76615dbd99842df4e8a68485de6d3b08,1.25;7675a465cecfd3530bd8e59a0261d1e0,5;0,50;0,50;76bd842334ff582d17899ef199708174,30;76bd8d84f8791c4bbfcb5f125960e0e5,3.75;76dc530502c89e5e4c0bed3fd15a8cfc,0;7709ae45eebc0215c84254539bda3cc1,2.5;772fcf047c0680bd8cedddc076fddf3a,2.5;0,50;77bb5c1d5ccf77312956101a5a2d5a13,11.25;77e8b5f5fe415a06ddc0f23d0b612715,55;77eb1a0c52a6eef5598838addc95c0d2,0;0,50;0,50;0,50;7843a14fc0e33e8b357c7febdd0ed3b1,2.5;78b3d3989a1bac2d9460227106642568,40;78b6f7c2bd410d5630adf0f818ffd2fd,2.5;78cca06accc3dd010c21839794a9f64c,100;0,50;78ecb33dc418ea29710b3cbcbb28fc5f,0;79170ca1effc2241932448a56497d2d1,2.5;791d37c59e6a69a16a7435eaee15a293,0;0,50;79404d3178533611e055ec6ce217febe,1.25;7987115b986329432dc76534bafe4e6f,70;0,50;79aa2f78dd3b498256329f38a3d0dd26,50;0,50;0,50;79c8043a8357e8d3bd7896ece94b2a75,6.25;79d2fe7ce53e9da58e46057dcf8a77fd,8.75;0,50;0,50;7a59adff9cc83bb250c799707b471f27,30;7a77ef9b53332b33f6b3da7d272fe9f3,5;7a914235a608c65081b80c042d791e62,8.75;7ace61f1014802fe81b54a3010a9df33,205;0,50;0,50;7b22c13c3215b6079b660516f49a48fb,1.25;7b67d6f60db3c7b6ca522f4053b3fb8d,17.5;7b959ab7a07f69bee9298d6e02bd279f,1.25;0,50;7be62091e23690131599b78a407a71d4,16.25;0,50;7c3d563b0a7c3add154b3898cb680fbb,1.25;7c5f972b68e36a5d77a769ed02b4654f,3.75;0,50;7cb8b976e88ac39ae432804a958e01d8,65;7cc14c02800fa9f735a5ac24bd97c5e1,18.75;0,50;7d0916a83604d236f3b16920fa7abaf4,130;7d0d73fe026d66fd4ab8d5d8da32a611,17666.67;7d55e7f404ea8e8e864ff44293955c4e,5;0,50;7dac77e698b9d2d5818e8b6ded9c9f07,2.5;7dee8104d63d1fafcb0316d99936e3fe,0;7e14853035a1ec4b8cbf5ed119905a0d,25;7e2b8f118f8ccb4dbdabe30037024beb,1.25;7e37ec0ac6f74f0003d2f8c9a6bfc257,2.5;0,50;0,50;7e9aa9011ac28c183ba83a062d0db3cf,30;7e9c3531c7c4195bd752c3bada2c8133,70;7ebf981404ad6666ef19900fdc57a28d,22.5;0,50;0,50;7f16240d40c64a3fdb4423ca4962f46e,7.5;7f29e4d3850c86c39c391c0a8d06a5c1,5;7f3b364e2389d856b66ba01b1e31d580,55;7fd9fd053ea6c0a36a9f7b3454650581,0;7ff0e4189059b5a0052024b9f76d9737,16.25;7ff7efe0736cb87c91a8ece3724fa6f3,15;7ff83ec004a31dc86b192d587ecc2cc0,445;80098a01e34612c74026aa1b8e28e5fa,40;8025034f7a1b558abe7281b01efeac5a,395;0,50;0,50;0,50;807d1e1242c7a13aae4387f17d60d917,190;808be5ba7b3ed74ee7729b81efacf34d,65;80b7efd3fa55603cc42966478cb78c68,0;80be6d1dafade67d4b22500be63f10da,1.25;0,50;0,50;810fad7a6da69dfc36b6b92998b562de,145;81227c7087fc6f129ece1f581a0c43a7,22.5;814f623b992ff570f852fb59023a4e2c,45;816962ec9fc7a2f957ae0f1cacbab185,3.75;816d4736b6196a357863cc458d98f7ee,355;81a7461a934473761f50b2293bff906d,0;81a92ab070c39bf76eb3f9a93ff38449,45;0,50;81e17b13b65a11ba2e4229baca4c28ff,1.25;8205e72f3b34b8dc8c2b8c12bce4f0b7,100;824309ae5aa6056c7d2f624735e22e96,1920;824bdc496abd278d3547a74b1e187f5c,30;82708dc6035dc5ab95a3b60768b3cf72,1.25;8276ae38c749efaf1ea86718a8b57c26,0;827c107a88077e037747e4566f42b76d,30;828806de8b5edeccf97a0c6474949d27,40;8296627e1c3a36e7b738a5ff9ae6ec99,1.25;0,50;82b97f9b6fe3c08af41b47f1a3a1a545,60;82c8cbf96c2e9b738dc6c9f126a21baf,1.25;82d3d460d700d9d25ebd320c799da24d,30;82d864c7cbbb8f26976f284158d0768d,18.75;82d9566bcdce6e595fbb96f505822b30,20;82e63a509a38e2201f08c819457df57f,190;83149ae4c6040ac57dce0b4efefa8234,1.25;8352e5f86cc7354a5f78e6c52ac51425,50;8353f971371c8ef14442c6eea1cc28f1,1.25;835ab55044fcfb6b251ea65316477544,2.5;0,50;837a7e6e8c63357e98e210c374be44ee,45;83c9e6f38a092010618cae143f592d6d,35;83f63c562e77bce0915860658199349d,40;8438a219b0732cbc80677e06744367d1,23.75;844c06c97c4561473a1964ebe92c1950,2.5;8458609bab772a46bfe99c33f88919cb,13.75;0,50;84851a8f818a50eb76f13d75091eebfe,5;0,50;84ad7a77b92b043bf29dfedf159f37a7,120;84add7fd7c247bbbebb8018d1405563d,40;0,50;0,50;84f86a1979e9010e563cb32c9f9dc795,1.25;851aecffd65c72fe5b86b9995135ac0e,0;853af9e03c6cd8dbdd8b6c058e7553b8,0;8565fc0b3981f2c9f8f776dea3a6e389,2.5;85d2fb39bd213fe70cc1ca4a48990175,23.75;85d784170cbe8b7aca0486c0759f07cf,1.25;85dccad71d6819824c320e4bae6dd168,5;85fc2169eda30a2c7182cdd1b989ae29,11.25;86033ac6c3dc972135de29848ccf07ae,1.25;0,50;0,50;865214b9ec64c1971278d6072e9c04ae,11.25;867059063c06af0c6e0e02139b346ede,23.75;8671d15b04a4995b5abe3fa7c7a046b5,1.25;0,50;869aab5ae1b4607cea502c3f1892336b,17.5;86b6adc1dd865f8112dda29f6ceda3fe,5;86b95fc21ee3fd877584235a6719baec,2.5;86d8d5c1c003ce5c64e6cd9fc209f77b,1.25;86f53023d7625df057d686ad7e0ce9ee,2480;870405e5518dc80048a6ddad44d86660,3.75;872c932dad25fe2353676ae0c4cabd2d,160;872cdbe307ff1e691f1662cfc667a99e,110;873ce4b030f4bac30909ee4b1da5c75e,1.25;87508ceceeb1bbbb783851745f37cabf,1.25;877a71bb0d710bed0fc0bd0a0abdfab6,8.75;877b5a17d915ca71838e1ad2f5832ae0,1.25;879a2cfba987d66a6aefc5c39ddd12d7,2.5;87b15299381f68c456d9f643d0de7645,7.5;87cf33d5c6955e376075b369664b2c2c,65;87f565aeef1dfb7d05953681fd76c8e8,0;87f98a3523f5a0b4cd0c7e0ca1f65a4b,1.25;880c3bf56ffb85c4f1c87f818c731825,1.25;8841e45da5fe1fc4ca36ff08815712a7,0;884aad43755491c6f2582a532aedd290,11.25;885a912ab004250d9acac308bdd45ccf,13.75;886702422e963414a67f100244e31a10,45;8873d40664afb7a2888b6996a6f1d934,0;88c3ff5d75a1ebcc557a55e377856fba,60;88d55617a02ddca5205cda9ae864508d,50;893c2358e05a568e04fd6f6895fce640,20;0,50;89a11d7381eabdd5f79aa7a39a305cde,21.25;89c03d27ba3d8fea5d79c11cf02e81dd,0;89ca38139ea44903ffc033ef3650bec3,25;89f29563670413ef999f5cd8788d9249,0;89f5b9af018c5dbe1ef962e8e90ac75c,2.5;89fce4f35d309f8836c273ef92e504de,145;8a0536862241b490f9535c1e7898d4f5,16.25;8a515cddaa85c4e801bc25940aafd0ed,1.25;8a697f1db694366187a9f39b76c69169,16.25;8a6d9a800685f5c12e29772d5f1736f1,13.75;8a729f66833fd4a5790fa0be6f43b407,18.75;8a7bea5d0bf3b94df2e25128e8296ca4,6.25;0,50;8accdb5bad8d53c63a869bd59fdb47cf,0;8ad825fc812bc4204b717d400ca7eadb,25;8addeceaf4a293953cbdd7f824655630,40;8b0489fe0870cca0a7bdf02d6527530a,1.25;8b36aba6e495729ca233c75b598e848b,1.25;8b3f6bd74b35a37d0366a530552fe968,0;0,50;8b65aa0565083dec90380d5961c632f4,0;0,50;0,50;0,50;8be05ed9d2ef0558db47ab3c436f5f70,20;8bec951f6364cb21bd80e8ab356d3286,55;0,50;8c1b89192e5c9ad449ee2f113aeb5ec4,2.5;8c2ff32c51ec8e64fb87b56e73ba67d2,6.25;8c44c95045ab874ab3528746ed508be2,2.5;8c603903f538729b857608c42c728744,1.25;8c6407908b7fb77b778c75bc3718eed3,1.25;8c7d8845cdab2ff5e78ac6ee648ee8ce,1.25;8c8744ca3866631f621851199aa79e49,18.75;8ca28f786f0d10c9cd1cf82002376593,0;8ca490434f9ce4267484fd50bca6b4b8,3.75;8cc1e7c6bfc5030c3609ac34083e92e7,1.25;8cfe9864e18db32a334b7de997f5a4f2,2.5;8d1e8747a1a646c7f151dbade2080c0d,0;8d2064a3c3770c27617e0f051b032be0,85;8d597e755c84b1c7c94576fc3fb71ff9,15;8d79c412f122c919e3ab0e9a4403a06a,220;0,50;8ea683bd15b54012632453e2bc9eec88,3.75;0,50;0,50;0,50;8ed4ce08bfd7cb8a436eef5fc3be322f,300;0,50;8f28c68d0416aedb02335227a8fa6bd5,3.75;8f2a530cf6f73647af4c680c3471ea65,18.75;8f4b9102b229931be807c600f9a39940,2.5;8f6c3ee5d5bb28b38993a36bbba99951,45;8fb9c5a279667f4f708a573177b181d7,0;8fbacfac0e9ed5531a31644db4d3d992,75;8fc591adaac5f6640de2d5231ca9a597,1.25;901a6902f3d9d9e0ad4e0615443650b5,25;0,50;9026df0876db6baa9189953a48b154c8,80;903142ea86a90491245f2db050aed14b,10;903639a81539f8914377ef81093db334,17.5;90693a20a36b40096861e10bd54c9c6f,45;906d42bcc2a97c2395b5ca63e86c9ef9,210;909f23bea314c9d6dae54a184c8f6ebc,25;90e2d1d879447e61d64721cde0ba022c,1.25;9115ebb5b5d7804845c129e3b6db4e84,30;0,50;9135d0ece716317424e7e97dfbd298dd,18.75;9161a6f065c66930d3087226c44bfb33,0;917a74b7252d8421919fb8fd95e04503,1.25;917fc4e4ccc94a357915f40a20886328,10;918b2c04316663ad3ac9497b28be3fa5,6.25;0,50;919bd42beb16cf6c1b8e661ce442a5e2,1.25;91b10f58e6bbd78a25b0d3d29b5c2b74,45;91d4293165966f36e63858d48b7f2e71,11.25;91d6e0b1fa9e6fe7d314abfefbb3d969,1.25;91eccec4234172a96844856bd5ff8445,5;92218020f781e3394c1ab563f7c197b7,125;924a190bb9827719e7c19b3107fe7fd6,30;924b67c8fae1438718e4f1a45f672256,1.25;0,50;92bb440b5971f12ac3187016335248cf,2.5;92c8569a5df359581f259b88697bce47,45;931de31c82c2eb781c9147dcab99d791,2.5;0,50;93442b07513251b6898a511448b0f4bc,0;9347d98a7f84f4661c67ded772f775f5,6.25;936557c6c8776e149c9fefc7a09076a1,40;937129ee4cb3630e5c46738eee9de716,1.25;9372be3bad2c306cc7908c971ee2f755,95;9379980588a20f5901f8e39bcec511f1,345;938d913651851c449ba9038fd9792f24,2.5;939c98982d9ed1adef26ece820a82cb9,1.25;939fc0c8146e62fd33e3afc0dfc3ff7d,0;93c8e4466049ec095ed49f3288766fca,1.25;93ceb5244472171ac60fbba931b5425d,18.75;93cf4607c73db6eab428bdfef00c8202,305;93d3db8d58f51ed195bc22fee7704f11,1.25;942f507f63bfc3d2acc6813b9f211ec0,35;942fea7c3eebcae5224ec1ee39bc4744,60;943720c9e4e032381c433dc85218eeb4,0;9444d2c0b9e95f8131857aa0a4a85767,1.25;945b7baa4d14950e26d011d1035caa30,295;947015bc3eb9a16504cd2965c61d5e9f,2.5;949b11ea5e95437e761ab3135e01d9fb,1.25;949d8ca1732fcf0c1fc03592885fc220,1.25;94bca6b48d5141b3ac0aee39f238b750,1.25;94caecac9ba0a36e7491227096e11d3c,80;94f177ac4578c2ef7eb07449f2ebd23f,45;94f5685db91571dc9427c8bcc5e18570,165;94f8a7dd4dc0f339e7a06a95d7f20f6b,12.5;9500838d2e318c0865b39a2bc50da6fd,45;951c43dea2277aa7ed5cae704776c8ce,3.75;953c793d357544378cb28b9909bf4b14,1.25;954cb52da98a631c03a8b7949fccf1db,0;0,50;0,50;9571771f896847f342404da0a27c6aaa,65;9578322bf6ed6904d031cbcef1b47fec,1.25;958ba027fc57c834e09b6c0a8720c525,22.5;95c0bffa80abceed2ee79956a72007d5,1.25;95c9eb521a131bb6ce0823f3abd5348b,20;0,50;95e2333ac75910113cf0c91bc16387f3,2.5;960cf47295873beea317d194a28e6e7b,17.5;965760845cc6d826f7356a925dc02639,5;0,50;0,50;967c3fe1bf9548e74102fd12eac5c415,1.25;96c18bb4a02d15c90224a7138a540cf7,165;96fb094c7cdfebde67e892e1abdf0299,6.25;974d2dd283bf0f3fa244b19aea3f8a4e,8.75;974e9147a71e9c605446fbf458f4e940,0;0,50;977f72ab4e75711cad31973d34d3e348,1.25;0,50;97ad757de2a58dbed7372a577537a647,35;97f0c66767b713c375065e4d5f627bff,7.5;97f2226a0a0607b5ad6414af35d3822b,6.25;985eb61cc2c1cc91446322bce97cfe81,1.25;9875b2fb19b438236448d0a58f53a93f,10;9899218c99fd054a335c949bf2b787ad,3.75;98a1b5909b653938c70966bba8d1f6b7,1.25;98c4b4e30516dabe245c354bdc32900e,21.25;98d94ac19226aafbbc08b9a8aeeec7a1,5;0,50;990f50a1c175d2799111b41a3e94ddc7,0;0,50;9932a00a946bd5be594b37fbd515bd65,11.25;9941b6bc707c57c555fb9ea38de0249c,1.25;996f951cf6784629e42d68316c67badb,6.25;997c441f7e4700499dea3802688d43b1,60;0,50;99e73e5980893dd3ef0fa40cd62c2742,50;0,50;9a05e4412e02d7eb45dcefc24a14e39e,6.25;0,50;9a2b963eea2f75326980ad6baec45c6c,8.75;9a516e998ffbcb50012f95726aebbf7f,185;9a6a96d819ec8599bc6e089a623bbc6b,1.25;9a6e86c370ed8f77ba858ec0a39cca28,2.5;9a7d7cc7743cbfbd46c10fb9af49c0d3,0;0,50;9aa6da0ccc916d31af1c01a49e879e79,65;9adc56c56dd00eba70480b41a9f5b853,1.25;9af6acde8acced8cfed406136cb7c4c7,60;9b06f2ae5a257ec5c8fb0b97b58498fd,260;9b1865a6bd3cac041f14e28e16b362c0,1.25;9b4366216e9870d5e68dd894d30463da,16.25;9b5b5d64fafa51599d6df9089b0b89b7,1.25;0,50;0,50;9b8d84ada9e5d6f3a424fc3d95df2529,3.75;9b93c87da0334b843551064d96e7a8cc,1.25;9b9479cc15df7f58fbdd39e9b844a145,2.5;9bc0e64cd2be1cce16b88052dd4263b0,2.5;9bc430dc724dac4041a8515174b72a1c,21.25;9bc8d2ac6e72e36e60ee62cac63703a8,0;9bd26aebe4841ef8d8a58ecfb2f8c0e9,1.25;0,50;9c38030605b8ba33fe4f33eaa3d27fb5,0;9c4d0ed01958c6629f88ee59b9698ad3,1.25;0,50;9c7a9918356fcd71706b66290e813b3a,3.75;0,50;9ccdb1509a91528db361258dfb7b8f13,15;9cde5e8a3063ff3dd3a8bb166810b85e,1.25;9ce6f19e20f69790601c9bf9c0b03928,0;9d1d9cc4d29e667f031fb3579b2c438d,0;0,50;9d59bbcfccd7b6008d1d06cc71c7e5b0,3.75;9d72d73334086cfc26bcc374cc5e605c,1.25;9d7ae806c4d2adb73085803b323dc583,175;9d88de6ad21612828f03e30c5f261b1f,2.5;9da1ce572047a46c7cf9c8ed0b5750d9,0;9dbd2eb638bfda3dc573a8e5f1ce7a4a,75;9dce8d5750fbdb4ccad73d2ca36491cc,3.75;9df1996b35117fae91b5e4c2b5e58da0,55;9e11265c322b34760cbfda934cda7aed,190;9e1f75d82ed70612da9ab8c896252192,25;0,50;0,50;9e55489b20a31882d5cd28b27c20d6d1,1.25;0,50;9e76ac2c2fc1ec4bbb5131e6fa5bd3c9,30;9e7773dab91402e2991ed6693c7e1b55,2.5;9e7d4a715b5ece9b6b4b3755096c287e,0;9e8ef708a0af85d2125526210a1b09ec,2.5;9ebb8337ef58e82fb58610d66b3fd0e0,1.25;9ee368d312180c16b1f1ce420d99067d,25;9f06b8972303f8a92ea6de6bbb7d3e9b,7.5;0,50;9f2fdd97fa9c48a05e9acc92d353fe51,165;9f55bb672f8875142b8c0e033e23412a,0;9f5d7eebad20f117d4f272d31bc6cfc7,105;9f8107021a0041e6f1e3281dad35edd2,1.25;9f9b938e36f7c76fd22ca717d1a122c5,10;0,50;9feee7ebc38c0e65cc7e9621ccd94bd3,0;9ff2b091f67327b7d8e5b75fb5337514,55;a01e61179405e7b8197d1ae64c5ecca0,1.25;a0462ef12d6f11deac43fb0fb3c8e86c,17.5;a06840d112d5e4f38bb2aee07e55f66b,2.5;a08d7ee9249461dba7b2118f8954ab78,40;a0a6fc891af36825ad565b4bd3e481bb,0;0,50;a0cd29783214d61a1156992554d8917c,25;a0d15c67aea509d42733de8b34093a2e,90;0,50;a0e2873abdd9e51b5fb6db6535e55b32,3.75;a125ffe948f87637f46e95a7e0602f8d,40;a143d41016594917eb15562fbd4c13c6,8.75;a14d965863860f0666915467dc995762,0;a16d8d4a3973ccbac0718046f0989521,30;a18928cbecb354d4584becce9eca6c13,0;a1a7ec74a3d57e759b536cde686b1783,85;a1bb632384f25c438a7cdfc8cf61fef0,1.25;a22d5bd1219eea1dbeecbb579140332e,45;0,50;a28a609ea96bbfbe7339aa6968d1f0a6,0;a2abc3473c6c04b559e930b8860eddd9,125;a2e48b7a0466a6166dab13ec6ca1bff5,13.75;a2f0290b48d5bf26bf6929b061a63b37,1.25;a30250fa1a0ef50fe0007c8104902f1f,1.25;a31f18125448a66891d1b7fa7cd0ca1f,1.25;a32321ad4c4e68bc654651353c811b49,1.25;a33641d2585f67df892c5df49b5c078d,7.5;a36b0f54f2e4a16c98e196271824aa4b,3.75;a39e2755d3ccee9f3dc176462abbc2f9,65;a3a40e2aac773f6559941a93dbf84b0c,23.75;a3b211057c07a294a1056bde2306d185,21.25;0,50;a3fe65d92f44b20b161d37ea8123f9e6,22.5;0,50;0,50;a414ba67c5d769da482d7c7928d1a112,0;a41bc3b54b1bd67360dafa1c849c5302,2.5;a433ca3195809625aefcd1f580658544,2.5;a457cb22fabdc732f458b08cbaa2ae55,35;0,50;a46d8cbea8b4312465e563c40e37ba88,190;a46f027711f5bc10665f3ae5d0fb6576,12.5;0,50;a4a0bcc56fc3f87168bd47bd4168cc3c,65;0,50;a4ad2bf1b6d0a92c704431c681835f62,0;a4c14e7d5df720a0ce60761b1f038ebe,1.25;a4c911b94acbefe491c74eff86200d55,2.5;0,50;0,50;0,50;a4ea31e2977ea1282eced091fa4b5713,35;a52565441ccda35464cf0d37fc9074f2,1.25;0,50;0,50;a57a2f1e3baae43b86d2d8ee3402382b,35;a5a0d2a7bc8f112fd96b5a8757e1460a,1.25;a5d8e471b08069888aa83b3c90b85a2f,2.5;a634bf74bde1366fbf40fcb87a543ca2,1.25;a65ca51c8316bf7ea9b8734436cc7a9f,0;a6a846cf62e78f73926bac0b4c914530,15;0,50;a6ead22d93ee4bcd6990c735131afe5e,7.5;0,50;a704f16709b443a7d69f46dae3a5b144,3.75;a724344aa68c31e548be784fd1315de6,5;a72de3671f89239a81b31d6f22eaeaac,18.75;0,50;a74ca5deed499696837703cefc83a465,12.5;0,50;a7a29947ccc7fa2ee5208c11e41fd3df,18.75;0,50;a7c2ade8c8adc9fa20dbdff227ddbe3a,1.25;a7c7b1ba0bb65e0f146394cc9447784a,5;a7e09bbd90b076eefe1c37de6c8ed48e,0;0,50;a8311e8a3d60fea0fd75237321594979,3.75;0,50;a86ca074987fa0cc3faa342c7f8e3b50,1.25;0,50;a88eb8379a7cff4fefe8e7f1c1777003,100;a8a06fa569f7e1660c945e525d80fa32,60;a8a8dc39a19d56b22056e749bf7e183a,1.25;a8b309319b4bc1f14326bf936740c0fe,0;a8b819e584c2e239ec02681955b362e2,6.25;a8dcc52bfe405432502d9fac62942d0e,25;a914310181ad14195a900132396544c1,10;a914eba952be5dfcf73d926b508fd5fa,8640;a92e1cf0903633d62283ea1f101a1af3,90;0,50;0,50;a95dde35d3895b73280b6d41356e882d,18.75;a982aa4401bce5673d9306cb6dda75e3,0;0,50;a9ad53bc5b800f172cbd82c399a7893d,2.5;a9bbb78a53bd09d0c8db03c8f066b22b,40;a9bc7b2387753c7c844bc7e61b91566e,1.25;a9c4e1b2658c0d9d768b2fae22ae50e4,0;a9dc57a8468f8a2a9ab997720ddb644b,3.75;aa1c62826fb9c377832292169da8b6e9,3.75;0,50;aa4e8d5c8034ea15fd48dcc77350e5a2,0;aa7a2a491a4c9401074824da31e80e6c,25;aa9d1fe2256a7b4acbd2b01cdda32262,0;ab3bbdab2853a95358fcbdac7bbd25c6,1.25;0,50;ab94b7bc3121d34456303a6ae55216ca,1.25;aba8c0c1ce4a848980e6b8968f6c2ec2,30;abd1069bf62bcdfdb598116545f1a619,2.5;abd97542ba87185962028cbba476a6d1,200;0,50;ac0197108f5d30d473524932a4be48a6,30;ac055890877ef30bf913520c616847be,1.25;ac3b104f7a72af92331928b440c422bc,12.5;ac7490e8706e8c4042d9b1279e9d69e3,85;ac8bf46b488d1e057ba12d87cc83c957,12.5;0,50;acb49921d52984b772f64edbb372ea3f,5;acc10b10ff1e7524e9437c7d6c69d75a,280;acd2b79de6dc22546ff09cb523f32cd2,12.5;acdb4c4d5407fc1d5924ae872dfd7107,0;0,50;ad25edf6f8d933d3adb8e6bec2c96e0b,1.25;ad5600a48803ae1b769481b10de7780f,2.5;0,50;ad8c5a5b7ec5c4a59e5682bf44601210,30;ad9214687bacbf598692c3e335a5f7f3,40;ad9a179dc17d3fa987bd75e3b71378cd,60;ada54ba1530f7a1da35eeffea69dc737,0;adc3eb2ed8d2b493d23454764a05ed26,23.75;adf65bc09bcd9aaa264d4f5ba19359ea,160;adf9f97e6dd40989780aec9c850a3507,1.25;ae2a04b31eb93905c803f43343ef43f2,110;ae517fa10fd6fb328a10e405155c67c8,2.5;ae519d6989ee92d547ccf3bed9a3dc92,11.25;ae51c3c4d96c1573460b621e9c636eff,17.5;0,50;aecdb1a31c390474f80269960a6e7554,35;0,50;aeed96e8131dca89a6b48b7843fa3585,13.75;af1c38f1b388a035c2d86551403c79d6,8.75;af5cf5f6c1867f07aebe79ac30271f17,420;af69a5ea70bb0019e498d01b49c9fa7d,110;af74c363e8256c31c2bb6b1e81036f43,6.25;af7ced0f604d5d564246c01a1883888d,2.5;0,50;afb18a65f36e3fdfb40abfdff18d9465,1.25;b003ccb7fb6870032b8e06afc722b29f,22.5;b0062d7045aec470cbe3da4df4e68fd7,35;b0151b1ee5b9120d200c9ce60c8d1b65,2.5;b030ad234200af452729cce82d2e61f3,6.25;b03475d1d799c030f86ba8cfefd88901,1.25;b03f006d263db8c3a2a236ad26eed373,55;0,50;0,50;b0a778e2e8b5e53f50fb27928d8ab695,245;0,50;b11e1383a0ca8efdc01343b4787456f3,30;b12b0b1af7c099ae3e185b16693868de,0;0,50;b13180e048e9d74ddcd433ad175441e6,3.75;b1346d96ccfc02780362db504f496f6b,265;b13f82b836ed9bf2f57691cee3244e8d,30;b15f2cdae1daf59f526f1693f9ceeece,235;b168a1682d6f6b584a7f39ce62836062,0;b1a9141cb44c2fe99fd7f9bd5693f820,0;b1d0940a97a70672583ee22fb93782d3,1.25;b1eb370d5351280a4e34e7c4044d3bf9,5;b1fc8162e7d4c87a9f3f02657c2a6ccb,65;0,50;b2193ff8ecd09f469f3dd08756c0e472,1.25;b2466b794ddce6d70366dcb2fb1643bd,1.25;b25561b5b84cc860263f42f1130abd7e,3.75;b2575dc73f67d71255f5314ac51364c8,30;b28ef0b6c2ceb0b0495a3d05a98593f5,65;b29e2459cad2d9aad31c18f115965f75,1.25;b2d5d0a71d91f6a113389422c0776c76,25;b2dc68c36d4480ad126526b3d15eda6e,1.25;0,50;b2e683d5cf03d198cd392bf92b4032a8,6.25;b2f5c7f5f3fb4f4d3ea014123d4386bb,3.75;b30ecea5c5b0ca174aca79952de6920e,1.25;b31c864842c3bebb80f25152facb74f6,10;b32781e071b939a1ece43414b3e26d47,1.25;b333bcf342d2731f2e54c1b5d926af99,12.5;0,50;b34b561f0b5f510dc93581b93ad53f46,6.25;0,50;b36240841e94dbaf29d803886c6f0c04,160;b3903e340e3c1a1028d483b2b0667a2d,3.75;b3962db8b6cc4036363dfe5ae7275db9,2.5;0,50;b3a1e7fde6300dacc5d63d9adad801ca,12.5;b3dc623f3dea8c64c595e756ba48aebd,1.25;0,50;b424b10aedcc61bef7479e2392b607f0,1.25;b45874e0a89d651596c7c18cd89d8804,2.5;b45c5017b7e7fbe7e7f0c672c78daf98,21.25;b461ea0ad6f85b2468aa41904603d53b,35;b48400ac220ded62db1acbc4b066a1c9,0;b48d086ec1a430a01dae25a7b1d98ae5,1.25;b4d3a28eb8f11f23941a57ce85e75277,6.25;b4e76e80c0313193767b725c763e323a,0;b500e4ffe6d55bd608d9aba62007cac0,45;b509d5c9a6dccd17e5f09f89a15264d8,1.25;0,50;0,50;0,50;0,50;0,50;b5e10faa93ed88c4f47b453d10fac9b7,0;b5f454b2ba97f071c27effccfade5518,10;0,50;b62cee6d4f1807941bee1bc80cc36aaa,25;b632801595f3f159b5b28b40cb9ff3da,2.5;b63506772e919758d70eef99e3443cf5,85;0,50;0,50;b643cdce38f04eeb90f6e45f03daed03,5;b697bbfcb028365be7f6918ac1e9407d,45;b6cdea9682421b12c02b4f13647731de,1.25;b6db9824c680138e278a681e1013bee6,8.75;0,50;b776ccf9f18b8cf291361dc12d6662d5,25;b7889a19cf219bf01205d412b076814f,155;b7a0a3abbcab708faf5b9fe810bd02a3,0;0,50;b7c492edd831e8ebe297be3cfe31d7c9,6.25;b7c805f71ca6f268ad3ae0aaa450de9f,0;b7df322e5467333d5a7a3155a48d30d3,70;b7ff0838d0db24e867f689fa52422ee8,3.75;b818c3cbcdb5c70483696c659d552e57,335;b8239d824b88c566b3ffd6c03b730bea,23.75;b837ffae734b258adde58c5ba921fc0b,105;b84e5be673dcff58e460d01d36a01e76,40;b84ec26ab43a1f2501fc77315aba2403,1.25;b858fcb0f02d895e8e9b7267db3600b7,60;b859cae986a8295617ed6d5108c5eb47,1.25;0,50;b873ec172bb68895d5f6346bcadff064,2.5;b87433f5ba606e735540c9f031b98209,12.5;b889671d094ab6040e62fe2da799626c,11.25;b89807c11a53dfa71cb72b2762d04710,16.25;0,50;b9706f29d7a6522f7a68a7627152ff32,6.25;b9959493fe44b3402f97c3f943ae86e7,0;b995db73712010cf0bd20af934150abc,1.25;ba3b677a0c10add7a97f884d8aa9205b,30;ba40858d2750cdc6f1104c81a645ef58,1.25;ba6c7b48d785785061230bedf7807ae7,17.5;ba7408ebef744206b8ede09057d079a2,11.25;ba999ecbe6f9a498861fabae3f6c37c5,70;baa2eefa36081bc3e8b9b8b90ee20d8c,13.75;baac67c78744d6227b1a5228c41820bd,13.75;bacc31c85bf4a107ee960dd9440cc2b9,2.5;bacd01143c821366687500f9e148a5d2,35;bad6a0a80491c5b2f5bd17cbfd395eb7,5;bb20208cbfcc61129f87c7e647dda84d,1.25;bb2a5ba9251d93f06ea305e1d26a38d1,1.25;bb58c7328641efe210aec477d12c88e6,1.25;0,50;0,50;0,50;0,50;0,50;0,50;bc6429ea11db5a18e556d5a50c49038b,6.25;bc6f45449edf33c2ae0ddd254c51d593,1.25;bcab56da59ba29e9694641f4f146272d,11.25;0,50;bcbc9d0ea201c4eeacae930b7e442c2f,1.25;bcf38e9cf02878882653e912cae3e683,1.25;0,50;bcfc37ef47a5b20a969f018791f1f7cf,3.75;bd1eef065111326bf9fd07d4cf6e6fc5,340;bd2d1762fda1d8361044b904e54b8afe,1.25;0,50;0,50;bd717ae76682132c9244ceeea199496b,30;bd73a30e5809c391354d67f48bdeb52d,2.5;bd74b8a57f40cf048155b0a1f681e53e,1.25;0,50;bdae3a19127a4323b98cc1f0eda1cc02,1.25;0,50;bdd600e5c31cbc96fc7307c487b9976b,1.25;be210af19352e87e87e97e85294c31b6,1.25;be4592de6391c7ac6a625b52b3962b35,45;be80b23cb27fedecff48571fcaff09aa,55;be84bc922cfd78b1d4dd49029abd4176,25;0,50;be97b8ec6af79072458cabe110c7b044,1.25;beb95ba3fa546e7c66e3e30c512b2355,25;bf25b5f8bdcabb40b572f6eee4712852,0;bf261cf83d07260c0940b5a3eeb83137,1.25;bf290719659eefbe83d30411471f7507,10;bf82f01e52a4e90a6490833e81e811c1,2.5;0,50;bfc3143a6f7122ec548aef0d4bca44e3,0;bfd4e6e64a9f79fd8fd01c6c4e770c81,650;0,50;bfdf121459720b33fa83d2c7770dbfd5,21.25;c0222eb9c021fa1591fda6b6bb0a89cb,13.75;c06664af2a4784903324689809503efd,0;c08c295934f3544eb4135b63405b123f,1.25;0,50;c0dba404454585ce1e2535559bdb9e0f,310;c0f4ca8597dd793c91ac89c801495f50,1.25;c1277afbd51d12fdbbe25d834a66ee5a,1.25;c12a1e87f383fb7e6fdc2edd6c097128,13.75;c175837ed24b4b1d1407ecef6b1ab667,35;c176e5642f12297d3fdb433de84f9822,830;c17c25f5f021a42957af31bedf6a9994,65;c1ba2ea33a74f9190177e1bac7e40431,5;c1f3fb1396318ece257b9c916ecfb18f,310;0,50;0,50;c20db07f878aedf7b0c04bd6bacc4ce3,60;0,50;c239bce0a139795e37e51a20bb8ae3dc,30;c25cf641cd41d5af8f565c077091393a,0;c261658bbe5b102deecd313e117a7015,30;c26ac599a7ff2db51705beeb944ead70,75;c26ea727fd2106cb3b3fef4d7e22e4ed,1.25;c2b4a7b9f608b794527cd15cdaba6eed,1.25;c2d1717bf74445b51f93697425839817,15;c2d3ce1e934551f89cc4f0d751370e84,0;0,50;c3074b767f96bfd75720983684025793,15;c3170a46ca0c1a681ccfefefe027ed07,25;0,50;c33a2e041ebf715a79cea6c68f910942,6.25;0,50;0,50;c37bc41c71d4e5abab03512e022d85da,25;c3845e6292dbf94b1fc9bd3ce70d45f3,0;c3963461abaa4ab13a5a5f3f2853b09f,17.5;c39c30f356f1f87007c6e11720787608,1.25;0,50;0,50;0,50;c3f4c7f511ee247988b45e5fd7617742,30;c417d71a3bb3c96c748211f47d0c0f19,0;c42ac059b20bfbd0afe568c36bec5b45,25;c43e521ab75c22903afec55505b9f1b1,110;c47018ba3d59d1f60da16a23dffb0658,1.25;c4770be6369f38a14783c48b7e5dea7b,5;c4a104885fc3d612853438d274030a2f,0;c4a2495b55d148818335f39bceb61b1c,8.75;c4b0aabb0caebb594b1da76618f40146,135;c4c652f102dcf42b627589d7d525c789,3.75;c4d048167482f20b01f180cf23122a23,20;c4db318d589144e55cfb5e96b466c4c0,17.5;c514c719a1cc8f62115c9276227ac113,1.25;c5173f65a8001fe6059fbccccc27bc4e,1.25;c51a18ab192533c5d70a08d342bf7c3e,65;c526e3cf603ed89708cf28e858aad85e,550;c55780fc7a0d44be0cffa580e77fae0a,0;c56ba004080f44227d94dac7a6b781a5,35;0,50;c5fad6dfecfa296b90a8925158c4e0a5,6.25;c60dc64585edc98b5623944982b1ec81,10;c637deacc83b5d8993a644dd12484c6b,12.5;c6b101787ad0ad59769f973c7d4966ab,1.25;0,50;c6bc916d7819e8eab9d95bad241e2435,0;c6e9086fc5a7bbf711707697fb33817d,225;c700b4aa2800eb4613fc934662812e24,1.25;c716829c59f4ef8e367f07733eb337ae,16.25;c7218b0752daed6a6ca80fcbac964c11,40;c731c9b8fac0b05cc31d9b0256af777c,0;0,50;c74e42d058cfcdbf39600d764fa3414b,1.25;c756e5563b6d8e2448efc8a0862303b8,1.25;0,50;c77a3eb2829443dc769847a4d591e7a9,0;c79db991a1bc7cb4c75ca0f1f24df7fb,2.5;c7c4dde3eff184e07d989e6e6bf75f33,1.25;c7ccda3dae6fef47946366c2661e39bb,1.25;c7cf030cbe5206f1f844ccda57fe00bd,75;c8155561cfc47848027361f577f944ce,1.25;0,50;c8251e31f31fe17f71be37f803e57a81,10;c82f000037c3fdd0394ce4fa4458cba2,17.5;c883318242324fae894a1bd18a6d44e3,0;c887daaa352145ca5f653d29252f253f,8.75;c8b9065ae71ac9f7a32d5612a0166c8f,0;0,50;0,50;c93868492b3982ba5de8d53786ca6402,7.5;0,50;c985528d26e10d6b8e26255b41c7cb51,13.75;0,50;ca1aa3d40f23899d168f0f4150a0890d,1.25;ca430c0e0bcb6692b56dd05d9af83902,40;ca4a7ebcebafc02b52dd14e62ee4cfd6,10;ca57e565b0974d98f54ebba0b6332f99,0;ca657fbf7b4d3fd03538951fb431716c,30;ca65d1dbbb67f4fc6aadaf7ab9aa704c,7.5;ca879b95370ed6a2aa5c110f04191705,35;caa5544470d2cf7a2acca74d641dd2a0,12.5;0,50;cad79df5783543aa14af8cd042586840,15;0,50;0,50;cb44d23b2c25625262ac95cfc5792b7e,75;0,50;cb61a738fa12189d9f86c75499a6b010,3.75;0,50;cb87d65dc32c31e5baf65e2c902d7cbd,45;cb9d674f651e94506d7e958d6c33dde0,1.25;0,50;0,50;cbbe01ae2c53cad990a6867a51255657,40;cbd1979bdb44004c1f60e39a1440b60d,0;0,50;cc1e0c9545fadadb2cb893ccd5c12fe8,40;0,50;0,50;0,50;cc51f625dc4fe751b2536395497e8d5c,3.75;0,50;cc83de229c1ef7c01917617eb42fe30d,1.25;cc9180bb8b4ae2228762373816a2f6df,1.25;cc9f0387941eb61ea992797c3b8448c4,11.25;0,50;cccb82cacfc5ae2141b841dfde457cee,3.75;ccee467a8990061b251b9317116ca46d,65;ccf17bd42891dbabaf6cb39c9d0f620c,10;ccf55d5679645385dd69569ed0ecea67,160;0,50;cd000f1edcd8836314cdef4419bee8ef,1.25;cd093f6b6564fa1cfb8e0a3ba8edf4b2,150;cd0d298ad7f6d5067255e31602bb79f0,2.5;cd0f1cd11b14758e973dcdfab23f2924,2.5;0,50;cd2080d1030caa8720436d5beeb47e4e,600;cd3a1c9e511731302ecb13de07abd2e1,15;0,50;cd555fcaecb704c9b5c1f746af1ea1d2,16.25;cd56c32db3da12d32336f281310d18d6,5;cd65a4ead4f98515a49d552d910b86ad,2.5;cd92b9525a14df746f32ca1f14513ffc,3.75;cd93800f551be75611cc940da9381575,1.25;0,50;cdebb7a5d0d053cc29216752a4e963d8,30;ce119a1ff7697b2654eba40ebb474d4c,17.5;ce171097a57524abef779a394f74027e,2.5;ce2a4b70c866643a115da634fc7f06fc,30;ce2e87e5bba0a9cd43d81323f86292cb,16.25;0,50;ce3b36a1b452dac04375a7f040f5bf09,0;ce80590611ae91bfc6a0f9d5abe78ca4,22.5;cef04e65569de69fd186d6dd04eab43e,7.5;cf05405e8849b470b69cd0f484f55a54,3.75;cf0ab57a90b8e5636678ed92aa92b08e,20;cf2fe6e349a5ee9499fa0e4a39428780,1.25;cf37b9889b85ef476daf8b6c7e495765,1.25;0,50;cfad046e75d87389427a1b034c5a6976,65;cfb288c7f80882f32053b9005d6674e0,10;0,50;d04faeb489d81f7aeec81c3ece576854,40;d07e1307a63d43a81694308403dc00b5,170;0,50;d0c9863fbb7dbd559e193728b113b6f8,80;d0fb25732bac5f737fbaac8e44d642c0,11.25;d1ac87f22acc49e02eca78a265da87ca,1.25;d1cce5bff444890ff305fe795cfe135e,0;d1eccdb51f04a5f810920566b0e1c7ec,10;d1fcb7b592d470788019165fe12e4aca,1.25;0,50;d220b61831401684da8455371797083c,7.5;d2256d43384f84d75809e3c30de02c54,70;d233be36cd8753d5240a67ea88534e63,10;d2973bc4e058225b6c6b8d674a587adb,2.5;0,50;d2ae4f8f2b4c17f15903b3a8af575814,0;d2ba1846426099335fd80b6014e92fb9,17.5;d2fd4fb5cda0b539bf1c01b215677cc2,10;d3166ebe9c237f34eef6882054cf8b9e,12.5;0,50;d3592ac732396dd67badd52d8179c0b6,25;d35a8d91b8c4d10a81223659c22648da,25;0,50;d370810314d56947fd409f3bac101f68,8.75;0,50;d3c4798b11f2ec3db9beeda4b626d55a,60;d3d915defdbe52a1883248cde241abb0,13.75;d3e0f595285bbf2861152ca9155aca50,25;d3f0c05f966ee25082508fb4312d144f,1.25;d3fc54191cda7c051b98b43a63aa2138,18.75;0,50;0,50;d4240940bca1728806404374628a94ce,60;d43ebeeed072f2fc1f319dcbbdc75afe,25;d444f9fe88f2090a3849de99fa2b2cd3,180;d4a3d5ce7156f0d1df4facda8eefeb00,40;d4d20c6261f943f219a6905c8eefea87,16.25;d4ddfa58d6dd446bc9b56c3e10a3c73f,3.75;d4e905365162436d3202686ddb030e0a,740;d50aeee27fb112d75b443b461d69dda8,0;d53c704ef532da4a5a3ccec067a820a6,30;d5442055aecdddfd13cad4502ab4b988,13.75;0,50;0,50;0,50;d570555e28a8eaa9a0dd11bc8322c913,6.25;d57b1f88653a2a0682dc38ac0dbac48d,55;0,50;d5d2a18cb59e4ee646fdc1f613fb59ca,25;d66c025649b6f364245ebebd4911849f,30;0,50;0,50;d68fba63eee863e16ea07ada91dbb1ca,1.25;0,50;d6ab669a47817d2be14e99bacfeb909a,13.75;0,50;d6eca3865584e1abee133495523d91ae,0;d6f6b5052c07f79393f9c7d480a072e6,2.5;0,50;d765d0ba0be982499d37ec2503bdfff1,6.25;d78af784aacb088a8ae3391e9b042519,30;d794a48fe6ac954c2fdf7f5d796493d9,7.5;0,50;d7c114c7247aa6ce9ca6e05167cae25b,75;d7c573668c47a2f8291e6b26fdd89e1e,7.5;d7d81a6d8f0fc797e95dac2dbebe598a,16.25;d80391a0c05e1c9ceedb74285f856684,105;d8063e963ca5e95a7761532113351538,2.5;d811112ee0c90355ed442f956bc4b5a9,0;d897a7af03f7d0cbffc725b73f94532c,240;d942b39f29225b34a89964d8eb807f5b,5;0,50;0,50;d98c249fb09259ca0c01af06e53bfa70,1.25;0,50;d9a400d3cb169759d782fd1c3e7f8737,1.25;d9a80edf50b72d71c37c947710ae8fbc,1.25;0,50;d9bb71a966fbbad06096aa65fbba302c,125;d9c4c66b39878b8c46d16cd854d96007,140;0,50;d9f155b039b7228aaeac39e2c2912a47,6.25;0,50;da2797fc982063d73cbda0fd3040292d,8.75;da5d2fd3724e90cae7042f9d97bce7ac,1.25;da7012c242d625075cd6567ad3f8f927,20;da7ddab9cd746320bd54c432afcd42f8,6.25;da928ae2f5e4d68db49a3adad0deca63,17.5;daacb150ae22fa6a8a5c9c5758700e8d,1.25;dab304d54593df6095cb318e46431fd8,0;db2147f681048bdadd89abb29316cd5c,65;db250f4451dc39632e52e157f034316d,1.25;db2a6eaec2b6ddd33bf08bfbd1b6f066,1.25;db3cf00a057e85fa2d8fa41cebca423c,30;db56b2226110fe3b9150c48e4dbe5549,0;db73605e4d2ce8191e050aaa9920ba8b,225;0,50;db7c06a43f9329b18678af84310c37d9,1.25;0,50;dbb6738b88abc133a57792a5b9687eba,15;0,50;dc388e0668eb5f840fa243f190b67ed0,5;dc595bd113c87ce124f30db28562f2db,7.5;dc5a16675b3e26c782c58eb8d9153a2f,0;0,50;0,50;dc8d6b9bb81cdbf77c16cde8ad7be576,2.5;0,50;0,50;0,50;0,50;dd81f4bdd35ad9b56f10add1332a6038,5;0,50;dd9e688a1678fe3d43528fd40125408a,435;0,50;ddd8907e136047f990e338fb8e900cad,0;0,50;ddf06989fc147d368f344119aacd9e6d,5;de0e4ddd50796fd8939cc374e7f14fb4,8.75;0,50;de2f2cafce158468e0f3ee1d5a2d46eb,35;0,50;deafe42f64d13ee6c57d8f79f6b1c7c9,10;decb378a7ce3d8bef9eb6ca94fd2d7a4,10;df1b3dac1826771584044adbb15dbe0a,1.25;df2d7e7503d83073d79b1f8fcb30e58b,120;df534d853f142580200a3eeda75c15f2,1.25;df7232dd951335d1a755ab9a4e6a3dd7,50;df7d22761815f216506930a8ef7ee981,5;df7f530c44ed255ee6684f6fd236f544,30;0,50;dfae80dc8a42940199e4051e3606ec7d,2.5;0,50;dfe216f7f2bd6dbf326b24f44c360e29,1.25;e0540c8b272b684d88ea8ce4c249dfcd,35;e0704ae07f54ae607f1f33e363fb6569,16.25;e0b20b1ccc088d2cefd7ec11f1239d4b,11.25;e0c31adda5289621ab94ca7fa271b718,0;0,50;0,50;e12f357fb11733a6e1bc6a3763e0b1c0,1.25;e1656b88687a2f7aefae0d193ebaa184,7.5;e177e7161f482279e555d4a1bb64b455,40;e1796a27e8ccc22fd482623940693700,17.5;e18ff5b8420dae26d49ec9e31b4d2c45,7.5;e19130745e8c56c8820c940fdd214a1b,18.75;0,50;e22005d619d5d1a0d2c6fbf882d3d4ae,480;e22bbcb684dcb3158b6c35a2b21273df,10;e2506ad0ff9277e852ec337d7ff86d57,120;e264291cf0ba4aafb965feaade38098f,3.75;e26766e435b8de6b16e1550ee4777927,45;e27aaf657905bd3fedc47c5570f2ee1d,18.75;e27c07aaa76212ef48770e2391633123,2.5;e2b2d51b337a559d07f7c3dfb79e32e9,2.5;e2bd93db54936cf3febcd8cf3b99fbea,400;e2cb397891774702086397ebd5376893,0;e2ce5a0ac3b1298c68f1010c0cafbeb5,115;e2e7dfc492e138dbe591bd136e447815,45;0,50;e325e988466d594d81feb3b27781a6de,0;e3302ff035030f0d2ca22f26b9c93012,6.25;e35f2e349c29296060d3f1ad52112d7d,20;e3609d2b817e65e79cdcba44c81e0538,0;e373665b11ba8869a310e5ffc8837b64,1.25;0,50;0,50;e3d2e26b764bda6c5e56338f09e5fb15,11.25;e3dbab06c42a46de0457314ca513c16e,22.5;e4027f17188b2a4ceda16cdbf1a8a965,0;e41cfa5a598151735ec6568fc94801ed,5;e41e9c4984d1640445e10bc3dd7da823,1.25;e474521b79aafeab8f5ce90a66df4aad,8.75;e47ec474e34e2256c426152b413101ac,1.25;e4b1ed8010a18456dbe158b6fdcdc0b5,1.25;0,50;e4d2d15b39f95f627094770b87e5b799,6.25;e4db42d47ed84bfbc5d492c6865bf6a9,0;e4eecfb50cae9c772fe597df7b2b8b8b,3.75;e4f4536c11db50b541309c4cc549d680,6.25;e503223b9d2ea770bef32e28c2fe3154,145;0,50;e52625f61028a2f4214a1010272c6754,8.75;e53253bd80d0c7c02ee6c8c44dc41e7b,45;e53ff8efab06a3bc0214dbf359006996,80;e546a0e0d5dc70b3819c59733ab7ff52,3.75;0,50;e59a6056bc2cbedf037e5d30fae0f293,6.25;e59d79b9fd799463f095ba14809dfde1,1.25;e5b4189e13aedee43992908678c6768a,100;e5c4f068970ea69d66293c52e7279117,50;e5cdc0c637cab4f382cbee77d9a9c2e7,55;e5d98ef2203fa1d1de8a6c618d4012e5,3.75;e5e0c31e740d02513dcc0f61f21195ca,2.5;e5e4fc4d91434914289aca9c26ebccd2,70;e602b53eba66086c5670bc7a0580598e,3.75;e60adf6eeb25da8aaf6ed2f460368189,35;e646fc78b3a208eafc93ed2a9c6fae6c,2.5;e64c6f0a50af958349a03ee08ab178f7,10;e657a1b036ef142b552530a6b1c4f000,1.25;0,50;e6baddf1b470948bc24945a53235666f,17.5;e6fc681905c70be383f241a409583e8f,2.5;e6fcd2a2a682f58c7b8dfdc1b3f511ca,1.25;e74b3cb10220fd68c13992c51944aa1a,18.75;0,50;e76d60df0d4d3a805b0c02ec1ecd97d6,0;e7b8d63b46a603066a30a11ddb09d12b,3.75;e7b92eee46f2ab71de912ca3a81ed7fb,40;e7c76a516a37c15b042f2104e64ce3a8,60;e7e1f46c60de55099250027f83047ab1,3.75;e7ee9336753c92457964dc5642157603,140;e7f90818e3e87c0bbefe83ad3cfe27e1,1800;e7fec928cdee35de86f445324c5a737d,60;e8221c27fd6cc3d013b3310e3c77f8a4,11.25;e82575126ae1757d17799801b9dba3a0,8.75;e8263087783a8e867bfe470a2c3d9d48,70;e826b4d9a8ef1f29a98c20cc1e49b740,2.5;e82bd3a56499ed19e181c47b571abf55,0;e830b1a54013d281112327170548e420,35;e831440cd7b84206cb59b5ef77009a8b,23.75;e83a29b54bc48c9744ad8d6faedae428,2.5;e853373f26dc687a2e93d3621aadda88,1.25;0,50;e87aa0e3e5883617b68779047b251f79,30;e87ef046cc85a35f3b0a195c884948e8,95;0,50;e8fa947974d4c988ae80ad58a08e48e1,3.75;e91e30977b7d4fa8f149d14d20e7dd24,6.25;0,50;e94141a22e697da191843afa05e6c904,1.25;e9495ef9260f39aeddacaa20615901f3,0;0,50;e9753d23ab741c303d0438eed79319b5,30;0,50;0,50;e9fd4e733a74f52e46d571af354613f0,1.25;ea0727f14d27e24812b5fd5344a4419d,16.25;ea0f18c16266883ae4cdb76668e8b709,13.75;0,50;ea37cf48b90fb0da5c1f67356708fbf3,7.5;ea4f828a360454b8e0037c28ab660914,3.75;0,50;ea8c491295c703b5f80845c395cb31b3,17.5;ea9eb4731e157f4f42a0787703feaa9f,1.25;eaafe5736443d064079b138a401acba5,1.25;eabf54836abe49b44a528a436878d2d3,16.25;eaf204f6018a7740499f38f046aebc1e,13.75;eaff669a66b76b28ef45536f0910770e,0;eb0968ab80847db6567668ac4ec44857,50;eb15325d77777f1b12a464fb77e92b33,22.5;eb17abc7d16b448cc0a293969c219dda,5;eb3e92107e6ee293fd7b9f4490e5c232,195;eb5c5f73284e9404bff846dcc5826055,1.25;0,50;eb809dcbabc4ad79dd59ed0e0315eb4d,1.25;ebdce453d46d7f6fda2bb84c8d4673c2,0;0,50;0,50;ec14f03fae87bfec46d1d8a0e11bbd3e,0;ec1b42453455011f6d26b5250a2eb7fe,1.25;0,50;ec59b47d79687a9ec41b0cdb0e0606d3,2.5;ec6957c5d419b45082f8c3a8ce54988a,2.5;ec8449805d56fb19486245eb2c961340,0;ec954793ff856045ed3df78ceec58d9c,170;0,50;ece77a55e80edca2e586f2a7e014b12e,0;ecfd9d1ea9efcd44fa96790459311e79,0;ed052f5ec33a2f3be76fe55705bf57c8,7.5;ed175b20c3e8ebd3607c4e53b65083bf,0;edaee446c871a16c3e4e9aa6fc895641,6.25;edd1d8b056c596eae60449a9de1040d5,0;ee0737bd4e0ca6955ac8fd75eeae34ae,3.75;ee2c8c9a73e894ec812ee0c16ebabd1d,40;ee56a9299d9b1accb9f23c3938ec14e7,0;0,50;eea3e62ef771958a7f1f1816cd7463fa,110;eeedef516fc6392b14c3968ee7ffb028,60;ef13334537e532cb9a5370a7571ed252,1.25;ef285b4434ca947168ec09b54336c68e,520;ef368a47ec318c792ea365add5f9f443,15;ef83f24a712864f1781209fb34eb0fa6,70;ef8d966919dd87939dad3d12e57a2c97,2.5;efac905a7a46c8c29fd25e56ef9ca3ed,5;efb2393c11f06d5f3773779a3430b6bd,60;efb40cd5c65bf1b472c056a34651c1df,0;0,50;efeaf597dd634038f79b48c8382baee6,200;eff724ef3f568039248fbfedb2643b67,13.75;0,50;f05fccd5308438d31a74348b726f390e,30;0,50;0,50;f0754c1f86499169dd6eac41e0760dc3,20;0,50;0,50;0,50;f0d3b07a58bd3bda83f6dcaadcda8364,2.5;0,50;0,50;f0e488d3d7532d6e4ce6a73d75f3ae67,12.5;f0edea95764d211864a91664d8383f4c,35;f10bf58f36e03780d0a50293af92cfaf,45;0,50;f140b0abe7873506ac7bf6de9f880238,0;f146924b614ffdc2d136f1d2111eaf00,10;f1716e8c0997925e02903f3d620a42e2,15;0,50;0,50;f1cda4e1a3da3b73bbe257ae33016789,2.5;f1d6e8d9fe4c2d559f1c64c9df81b5d2,35;f1f812690323f26cd060034e4a183e50,0;f216b0c43b6ca4dd82c96c9bc80fde9c,6.25;f23c5d6832cd13b654597a02407470f6,115;f249fe61b1a5393ec5b9573db5ffe603,0;0,50;f2a3de0c8699ec9f7bee3fbe3e25e9b8,1.25;0,50;f2eb91afb78475d95e118e314e48f879,60;f300094df21f5bf6f373ac7da9239aed,3.75;f305c82758d637897aa099375f5170c6,5;f308880ca618e62d5cf7b7912ca1da00,11.25;f32eb8f17277674ca22558672b671622,270;f339ee6ef7cbf22619b03bfa34e5a4a0,1.25;f34b4767ef9b5944a3c392ed4e69a7a0,30;f362f7a1cd00a16e9d91740a6723af01,15;f3bc8e8c111c75bf02069df5df2e4643,6.25;f41f66b1a3490ad155786f6ddd1f16d5,670;0,50;f46d4755f17cfaed68bf7af707b1731e,2.5;f499872d1adc698fe0145896867069e0,65;0,50;0,50;f4c2e734e30003267df86da64c670bc1,1.25;0,50;f4d70940fd6330add993460d81593b87,30;0,50;f4f801169d83eb1d4eca862edb12522a,1.25;0,50;f51b483c50a7438f647ceae05459979b,7.5;0,50;f5370e8abdeba6a9a85e690c3a080508,0;f54f51af9ccd1bb3b38fcd02e290b997,8.75;f55273555197291a829d2e88d15bc595,17.5;f557ab9342b11e3980c12f4ef72fecde,1.25;f5bc3c415aa30caf0cf987fa6200feda,30;f5cce458fb3532c38dd1757b8fbe9eca,100;f5e450ad342fb8be0e5855717df92a44,1.25;f5e5133282f34c97a70111a4a79fa110,40;f610b73eb55a4b5947da724503a8f4e4,1.25;f61973ca0b0c665ab69fcdaa164ddca2,16.25;f61bd18142e8ccfd5907f1a4e1bbcb7f,1.25;f62692de79443635fa77a13756506616,1.25;f627742aed8627f590792f711c651913,235;f62f1c9cf854337001f5479fe4ce4115,45;f636448e64b48e26aaf610a48a48bb91,35;f63b0e183a641ad9afce477e6be19d2c,90;f697feb4e17a75eded452dee9e8eaaa0,1.25;0,50;f6a5fdbf4e0742e13e3937b68ed76739,40;f6b8908b4e1f90b11fc7737745576e9e,0;f6c06728e018a2a087b0163173b5df23,1.25;f6c8aa817ca3f418a8024efcf57a47b0,80;f6d0bb6b841c35d9fd0a4c8ac085513a,5;f6e9b9c140a2363fd623bfe0048f2425,3.75;f6ea44c6b89a6e4bbb14fe2c271ee306,3.75;f6eee1f53dabdb723178a21d40ff9b66,30;f72659fbed483943f15529be3e7995c0,5;f741f32896132998d351ed7d4af46d8b,13.75;f745d4316d1f4bcaa35a9006e0375a0c,0;f7478106736d348e0a65cc8e7b612d4c,1.25;f76d9c65b2a7fdd1b25166ae9418782b,7.5;f7b0e67c24c8b4f3b40ab74e5229e2c2,1.25;0,50;0,50;0,50;0,50;f85d969512b3394e3c613af468d1d18a,3.75;f87439dbc95e4e2b1175e3ca167d1191,0;f879c988e11e41cf95a30e175ec36b03,1.25;f8ad6212e13e1ace2220547b03ab8241,35;f8b0a6058dc95edd042224b433fb8148,16.25;f8ce1bcad9522fa360cd0aee2896430f,0;f8de81a8e1677ef7566ef5ae8dedd3ea,0;f8fab9b305ab0a92b976e51b386650e6,20;f928fc0d1294eb0e30f84c3a78f0710e,1.25;0,50;f939f4c13f77cf895f88e730a71f84d4,2.5;f93f304cb0a115a0a6ff44ca70382617,0;0,50;f959e06d7e600d8c83308df529337ebd,1.25;f977703c3a06398c85ac8e34968c8b9e,13.75;f9b3222c3c184dad559ffe5d9a96a4fe,10;f9d951f6684cc848bf84e3f6d82a8346,5;0,50;fa2bdc16b2ff029a58754aa8f215a8dc,10;0,50;fa657b93230f7780255e96bfc6706508,12.5;0,50;0,50;fa9ddca42826c424790da17ce66516c8,0;faa19ea4586e0f4bc26e6b1ae9240eff,110;faaacaef940b86739122307c6f431e9f,0;fadb537b59fb0e583308c118f344a4d1,1.25;fafb051b15c210b801ef0ab91ddf3a6d,2.5;0,50;fb06b007fe0f6df268b97bbdbf84485d,30;fb3f0673803f915287cd5ac3a3394e66,18.75;fb411d4675c1a0360e132df8d41c6046,5;fb7b6e3eac813306bf7e4292b8a7d3a4,2.5;fb7c8f84f10b3047cfece557362f5aa8,7.5;fb82958a236badb38e03062ae6d3824d,1.25;fb8e05bcd40fdf70fda131d4f8b84c13,8.75;fbaa9ad38365baf185e3db993677dd25,150;fbafd481fda92df08cc3f2e2515778ec,120;fbb39e73dcda2b7b5e13410b86b789f8,25;fbdf05466d41d356c65a79fe889487a0,115;fc38b066fe61f9b30ed6598c52a7daeb,17.5;fc5a68fee2be7fd048659f9ed5b6a4a6,0;fc95227bbbb1faa342eda16273ba349e,0;0,50;fccf2906585418c2e5872d2307648574,1.25;fcde05657ae4b0f0fb6bae43b9828886,0;fcf9724f35aad0589d82d715f78e9d06,17.5;fcf9ee463557e206157a53eaaf7172f2,10;0,50;fd027184a76b0df0fdebcbfab58bf3dd,45;0,50;fd088cedd63db49029a5ce5546f554fb,5;fd218494f0ee4ee3dc880eeb84ddc586,5;fd25c3e54e51190721bbc15c5085a508,3960;fd5ef6cdb1c2611dc39e106faea20bb7,35;fd7e0fb6336dcf1f13e40e7615f4d959,35;0,50;fd8bf94446105ffa781c54414e287dc6,110;0,50;fda0739e22e485f9c8cf0fcda1ec443f,23.75;fdb1b1c8a8a9d432d7ca52c17508efb6,25;fdb8dfc010b5e72295e4abf530876ed9,55;fdc4e9c8c0ae77b5efac53572bd06fb6,1.25;0,50;fdc7e04c70a57f8963fb823f619e8964,35;fdc9f8dc8c895c58c0fea2ca0ce6f33f,70;0,50;0,50;fe049f0aef553206d250a1aad96b768d,1.25;fe43ab277aa6e250ec69786f49228feb,95;fe44ffc77e2aa4c02cda8030b56778c7,1.25;fe4779e3fd259df872637a06a5dcfdba,1.25;fe4a710fb94501cd94aabd1ed17b6a56,1.25;fe589c27312749002ad709e8550a74f9,0;fe5a5a60f8a1f286b41f262b1c7cddfc,2.5;feb61fcd66f07a1b4b6348182cd46806,3.75;feead2f7fbcac15d701b476995871850,1.25;ff21232db03e256f9318f739185ee0d8,2.5;ff23b176b8b8ca7d3fe2a6c0c66323b2,35;ff5efaa7038368c3e1a61e28f175f961,0;0,50;ff8abb632fbf890dd269aca3c2cb044a,0;ff9195b402d9fce448863768acbf1d12,22.5;ffa2c11600a224854d0d29e5a0d2ab9e,0;ffb45ad8a3dfa9c3543f836740ba0224,30;00000000000,275000;"; const std::string packed = PackBinarySuperblock(contract); const std::string unpacked = UnpackBinarySuperblock(packed); @@ -130,5 +129,10 @@ BOOST_AUTO_TEST_CASE(gridcoin_V8ShouldBeEnabledOnBlock312000InTestnet) fTestNet = was_testnet; } +BOOST_AUTO_TEST_CASE(gridcoin_cdblShouldRoundToDouble) +{ + BOOST_CHECK_EQUAL(3.14, cdbl("3.1415", 2)); +} + BOOST_AUTO_TEST_SUITE_END() From 6453e3b8d2ec9bf881486f0051373f6c716eca8b Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 12 Oct 2017 09:06:59 +0200 Subject: [PATCH 043/166] Rename cdbl -> RoundFromString and move it to util. --- src/main.cpp | 75 ++++++++++++++++--------------------- src/main.h | 1 - src/miner.cpp | 2 +- src/qt/bitcoingui.cpp | 1 - src/rpcblockchain.cpp | 62 +++++++++++++++--------------- src/test/gridcoin_tests.cpp | 7 +--- src/test/util_tests.cpp | 5 +++ src/util.cpp | 5 +++ src/util.h | 13 ++++++- 9 files changed, 87 insertions(+), 84 deletions(-) mode change 100644 => 100755 src/miner.cpp mode change 100644 => 100755 src/qt/bitcoingui.cpp mode change 100644 => 100755 src/util.cpp mode change 100644 => 100755 src/util.h diff --git a/src/main.cpp b/src/main.cpp index e5fc1c3be4..7f05098e39 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1965,7 +1965,7 @@ int64_t GetProofOfStakeReward(uint64_t nCoinAge, int64_t nFees, std::string cpid if (sTotalSubsidy.length() > 7) { sTotalSubsidy = sTotalSubsidy.substr(0,sTotalSubsidy.length()-4) + "0124"; - nTotalSubsidy = cdbl(sTotalSubsidy,8)*COIN; + nTotalSubsidy = RoundFromString(sTotalSubsidy,8)*COIN; } } @@ -2002,7 +2002,7 @@ int64_t GetProofOfStakeReward(uint64_t nCoinAge, int64_t nFees, std::string cpid if (sTotalSubsidy.length() > 7) { sTotalSubsidy = sTotalSubsidy.substr(0,sTotalSubsidy.length()-4) + "0124"; - nTotalSubsidy = cdbl(sTotalSubsidy,8)*COIN; + nTotalSubsidy = RoundFromString(sTotalSubsidy,8)*COIN; } } @@ -2586,7 +2586,7 @@ double BlockVersion(std::string v) if (v.length() < 10) return 0; std::string vIn = v.substr(1,7); boost::replace_all(vIn, ".", ""); - double ver1 = cdbl(vIn,0); + double ver1 = RoundFromString(vIn,0); return ver1; } @@ -2699,7 +2699,7 @@ std::string UnpackBinarySuperblock(std::string sBlock) std::string sBinary = ExtractXML(sBlock,"",""); if (sBinary.empty()) return sBlock; std::string sZero = ExtractXML(sBlock,"",""); - double dZero = cdbl(sZero,0); + double dZero = RoundFromString(sZero,0); // Binary data support structure: // Each CPID consumes 16 bytes and 2 bytes for magnitude: (Except CPIDs with zero magnitude - the count of those is stored in XML node to save space) // 1234567890123456MM @@ -2748,7 +2748,7 @@ std::string PackBinarySuperblock(std::string sBlock) { std::string sPrefix = "00000000000000000000000000000000000" + ExtractValue(vSuperblock[i],",",0); std::string sCPID = sPrefix.substr(sPrefix.length()-32,32); - double magnitude = cdbl(ExtractValue("0"+vSuperblock[i],",",1),0); + double magnitude = RoundFromString(ExtractValue("0"+vSuperblock[i],",",1),0); if (magnitude < 0) magnitude=0; if (magnitude > 32767) magnitude = 32767; // Ensure we do not blow out the binary space (technically we can handle 0-65535) std::string sBinaryCPID = ConvertHexToBin(sCPID); @@ -4972,12 +4972,6 @@ std::string RetrieveMd5(std::string s1) } } -double cdbl(std::string s, int place) -{ - return Round(atof(s.c_str()), place); -} - - int GetFilesize(FILE* file) { int nSavePos = ftell(file); @@ -4988,9 +4982,6 @@ int GetFilesize(FILE* file) return nFilesize; } - - - bool WriteKey(std::string sKey, std::string sValue) { // Allows Gridcoin to store the key value in the config file. @@ -5978,7 +5969,7 @@ double ExtractMagnitudeFromExplainMagnitude() { std::string sSubMag = vMyMag[1]; sSubMag = strReplace(sSubMag," ",""); - double dMag = cdbl("0"+sSubMag,0); + double dMag = RoundFromString("0"+sSubMag,0); return dMag; } } @@ -6000,8 +5991,8 @@ bool VerifyExplainMagnitudeResponse() double dMag = ExtractMagnitudeFromExplainMagnitude(); if (dMag==0) { - WriteCache("maginvalid","invalid",RoundToString(cdbl("0"+ReadCache("maginvalid","invalid"),0),0),GetAdjustedTime()); - double failures = cdbl("0"+ReadCache("maginvalid","invalid"),0); + WriteCache("maginvalid","invalid",RoundToString(RoundFromString("0"+ReadCache("maginvalid","invalid"),0),0),GetAdjustedTime()); + double failures = RoundFromString("0"+ReadCache("maginvalid","invalid"),0); if (failures < 10) { msNeuralResponse = ""; @@ -6030,14 +6021,14 @@ bool SecurityTest(CNode* pfrom, bool acid_test) bool PreventCommandAbuse(std::string sNeuralRequestID, std::string sCommandName) { bool bIgnore = false; - if (cdbl("0"+ReadCache(sCommandName,sNeuralRequestID),0) > 10) + if (RoundFromString("0"+ReadCache(sCommandName,sNeuralRequestID),0) > 10) { if (fDebug10) printf("Ignoring %s request for %s",sCommandName.c_str(),sNeuralRequestID.c_str()); bIgnore = true; } if (!bIgnore) { - WriteCache(sCommandName,sNeuralRequestID,RoundToString(cdbl("0"+ReadCache(sCommandName,sNeuralRequestID),0),0),GetAdjustedTime()); + WriteCache(sCommandName,sNeuralRequestID,RoundToString(RoundFromString("0"+ReadCache(sCommandName,sNeuralRequestID),0),0),GetAdjustedTime()); } return bIgnore; } @@ -6764,7 +6755,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { // To prevent abuse, only respond to a certain amount of explainmag requests per day per cpid bool bIgnore = false; - if (cdbl("0"+ReadCache("explainmag",neural_request_id),0) > 10) + if (RoundFromString("0"+ReadCache("explainmag",neural_request_id),0) > 10) { if (fDebug10) printf("Ignoring explainmag request for %s",neural_request_id.c_str()); pfrom->Misbehaving(1); @@ -6772,7 +6763,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } if (!bIgnore) { - WriteCache("explainmag",neural_request_id,RoundToString(cdbl("0"+ReadCache("explainmag",neural_request_id),0),0),GetAdjustedTime()); + WriteCache("explainmag",neural_request_id,RoundToString(RoundFromString("0"+ReadCache("explainmag",neural_request_id),0),0),GetAdjustedTime()); // 7/11/2015 - Allow linux/mac to make neural requests #if defined(WIN32) && defined(QT_GUI) neural_response = qtExecuteDotNetStringFunction("ExplainMag",neural_request_id); @@ -7189,16 +7180,16 @@ MiningCPID DeserializeBoincBlock(std::string block, int BlockVersion) surrogate.projectname = s[1]; boost::to_lower(surrogate.projectname); surrogate.aesskein = s[2]; - surrogate.rac = cdbl(s[3],0); - surrogate.pobdifficulty = cdbl(s[4],6); - surrogate.diffbytes = (unsigned int)cdbl(s[5],0); + surrogate.rac = RoundFromString(s[3],0); + surrogate.pobdifficulty = RoundFromString(s[4],6); + surrogate.diffbytes = (unsigned int)RoundFromString(s[5],0); surrogate.enccpid = s[6]; surrogate.encboincpublickey = s[6]; surrogate.encaes = s[7]; - surrogate.nonce = cdbl(s[8],0); + surrogate.nonce = RoundFromString(s[8],0); if (s.size() > 9) { - surrogate.NetworkRAC = cdbl(s[9],0); + surrogate.NetworkRAC = RoundFromString(s[9],0); } if (s.size() > 10) { @@ -7206,15 +7197,15 @@ MiningCPID DeserializeBoincBlock(std::string block, int BlockVersion) } if (s.size() > 11) { - surrogate.ResearchSubsidy = cdbl(s[11],2); + surrogate.ResearchSubsidy = RoundFromString(s[11],2); } if (s.size() > 12) { - surrogate.LastPaymentTime = cdbl(s[12],0); + surrogate.LastPaymentTime = RoundFromString(s[12],0); } if (s.size() > 13) { - surrogate.RSAWeight = cdbl(s[13],0); + surrogate.RSAWeight = RoundFromString(s[13],0); } if (s.size() > 14) { @@ -7222,7 +7213,7 @@ MiningCPID DeserializeBoincBlock(std::string block, int BlockVersion) } if (s.size() > 15) { - surrogate.Magnitude = cdbl(s[15],0); + surrogate.Magnitude = RoundFromString(s[15],0); } if (s.size() > 16) { @@ -7234,7 +7225,7 @@ MiningCPID DeserializeBoincBlock(std::string block, int BlockVersion) } if (s.size() > 18) { - surrogate.InterestSubsidy = cdbl(s[18],subsidy_places); + surrogate.InterestSubsidy = RoundFromString(s[18],subsidy_places); } if (s.size() > 19) { @@ -7254,19 +7245,19 @@ MiningCPID DeserializeBoincBlock(std::string block, int BlockVersion) } if (s.size() > 23) { - surrogate.ResearchSubsidy2 = cdbl(s[23],subsidy_places); + surrogate.ResearchSubsidy2 = RoundFromString(s[23],subsidy_places); } if (s.size() > 24) { - surrogate.ResearchAge = cdbl(s[24],6); + surrogate.ResearchAge = RoundFromString(s[24],6); } if (s.size() > 25) { - surrogate.ResearchMagnitudeUnit = cdbl(s[25],6); + surrogate.ResearchMagnitudeUnit = RoundFromString(s[25],6); } if (s.size() > 26) { - surrogate.ResearchAverageMagnitude = cdbl(s[26],2); + surrogate.ResearchAverageMagnitude = RoundFromString(s[26],2); } if (s.size() > 27) { @@ -7528,8 +7519,8 @@ void HarvestCPIDs(bool cleardata) InitializeProjectStruct(structcpid); int64_t elapsed = GetTimeMillis()-nStart; if (fDebug3) printf("Enumerating boinc local project %s cpid %s valid %s, elapsed %f ",structcpid.projectname.c_str(),structcpid.cpid.c_str(),YesNo(structcpid.Iscpidvalid).c_str(),(double)elapsed); - structcpid.rac = cdbl(rac,0); - structcpid.verifiedrac = cdbl(rac,0); + structcpid.rac = RoundFromString(rac,0); + structcpid.verifiedrac = RoundFromString(rac,0); std::string sLocalClientEmailHash = RetrieveMd5(email); if (email_hash != sLocalClientEmailHash) @@ -7544,8 +7535,8 @@ void HarvestCPIDs(bool cleardata) structcpid.errors = "CPID calculation invalid. Check e-mail address and try resetting the boinc project."; } - structcpid.utc = cdbl(utc,0); - structcpid.rectime = cdbl(rectime,0); + structcpid.utc = RoundFromString(utc,0); + structcpid.rectime = RoundFromString(rectime,0); double currenttime = GetAdjustedTime(); double nActualTimespan = currenttime - structcpid.rectime; structcpid.age = nActualTimespan; @@ -7739,7 +7730,7 @@ MiningCPID GetMiningCPID() void TrackRequests(CNode* pfrom,std::string sRequestType) { std::string sKey = "request_type" + sRequestType; - double dReqCt = cdbl(ReadCache(sKey,NodeAddress(pfrom)),0) + 1; + double dReqCt = RoundFromString(ReadCache(sKey,NodeAddress(pfrom)),0) + 1; WriteCache(sKey,NodeAddress(pfrom),RoundToString(dReqCt,0),GetAdjustedTime()); if ( (dReqCt > 20 && !OutOfSyncByAge()) ) { @@ -8656,7 +8647,7 @@ std::string GetQuorumHash(const std::string& data) if(sCPID.size() != 32) continue; - double dMag = cdbl(vRow[1],0); + double dMag = RoundFromString(vRow[1],0); sHashIn += CPIDHash(dMag, sCPID) + ""; } @@ -8755,7 +8746,7 @@ bool IsSuperBlock(CBlockIndex* pIndex) double SnapToGrid(double d) { double dDither = .04; - double dOut = cdbl(RoundToString(d*dDither,3),3) / dDither; + double dOut = RoundFromString(RoundToString(d*dDither,3),3) / dDither; return dOut; } diff --git a/src/main.h b/src/main.h index 2586dca6d3..809a4f8160 100755 --- a/src/main.h +++ b/src/main.h @@ -261,7 +261,6 @@ bool OutOfSyncByAge(); bool NeedASuperblock(); std::string GetQuorumHash(const std::string& data); std::string ReadCache(std::string section, std::string key); -double cdbl(std::string s, int place); std::string GetNeuralNetworkSupermajorityHash(double& out_popularity); std::string PackBinarySuperblock(std::string sBlock); std::string UnpackBinarySuperblock(std::string sBlock); diff --git a/src/miner.cpp b/src/miner.cpp old mode 100644 new mode 100755 index b2c022ab83..8b0a3dbb10 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -678,7 +678,7 @@ int AddNeuralContractOrVote(const CBlock &blocknew, MiningCPID &bb) if(!NeedASuperblock()) return printf("AddNeuralContractOrVote: not Needed\n"); - int pending_height = cdbl(ReadCache("neuralsecurity","pending"),0); + int pending_height = RoundFromString(ReadCache("neuralsecurity","pending"),0); /* Add our Neural Vote */ bb.NeuralHash = sb_hash; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp old mode 100644 new mode 100755 index 7e98a98d3c..f0f4035ba8 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -122,7 +122,6 @@ json_spirit::Array GetJSONPollsReport(bool bDetail, std::string QueryByTitle, st extern int64_t IsNeural(); -double cdbl(std::string s, int place); std::string getfilecontents(std::string filename); int nRegVersion; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 2cf5574739..80c09b6d20 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -665,7 +665,7 @@ double GetSuperblockMagnitudeByCPID(std::string data, std::string cpid) if (vSuperblock[i].length() > 1) { std::string sTempCPID = ExtractValue(vSuperblock[i],",",0); - double magnitude = cdbl(ExtractValue("0"+vSuperblock[i],",",1),0); + double magnitude = RoundFromString(ExtractValue("0"+vSuperblock[i],",",1),0); boost::to_lower(sTempCPID); boost::to_lower(cpid); // For each CPID in the contract @@ -748,7 +748,7 @@ bool TallyMagnitudesInSuperblock() if (vSuperblock[i].length() > 1) { std::string cpid = ExtractValue(vSuperblock[i],",",0); - double magnitude = cdbl(ExtractValue(vSuperblock[i],",",1),0); + double magnitude = RoundFromString(ExtractValue(vSuperblock[i],",",1),0); if (cpid.length() > 10) { StructCPID stCPID = GetInitializedStructCPID2(cpid,mvDPORCopy); @@ -801,7 +801,7 @@ bool TallyMagnitudesInSuperblock() if (vProjects[i].length() > 1) { std::string project = ExtractValue(vProjects[i],",",0); - double avg = cdbl(ExtractValue("0" + vProjects[i],",",1),0); + double avg = RoundFromString(ExtractValue("0" + vProjects[i],",",1),0); if (project.length() > 1) { StructCPID stProject = GetInitializedStructCPID2(project,mvNetworkCopy); @@ -809,7 +809,7 @@ bool TallyMagnitudesInSuperblock() stProject.AverageRAC = avg; //As of 7-16-2015, start pulling in Total RAC totalRAC = 0; - totalRAC = cdbl("0" + ExtractValue(vProjects[i],",",2),0); + totalRAC = RoundFromString("0" + ExtractValue(vProjects[i],",",2),0); stProject.rac = totalRAC; mvNetworkCopy[project]=stProject; TotalProjects++; @@ -835,7 +835,7 @@ bool TallyMagnitudesInSuperblock() if (vQ[i].length() > 1) { std::string symbol = ExtractValue(vQ[i],",",0); - double price = cdbl(ExtractValue("0" + vQ[i],",",1),0); + double price = RoundFromString(ExtractValue("0" + vQ[i],",",1),0); WriteCache("quotes",symbol,RoundToString(price,2),GetAdjustedTime()); if (fDebug3) printf("symbol %s price %f ",symbol.c_str(),price); @@ -1236,7 +1236,7 @@ Value execute(const Array& params, bool fHelp) return results; } - double dAmount = cdbl(sAmount,6); + double dAmount = RoundFromString(sAmount,6); if (dAmount == 0 || dAmount < 0) { @@ -1448,7 +1448,7 @@ Value execute(const Array& params, bool fHelp) std::string sAmount = vReward[1]; if (sAddress.length() > 10 && sAmount.length() > 0) { - double dAmount = cdbl(sAmount,4); + double dAmount = RoundFromString(sAmount,4); if (dAmount > 0) { CBitcoinAddress address(sAddress); @@ -1785,7 +1785,7 @@ Value execute(const Array& params, bool fHelp) printf("CPIDAge %f,StakeAge %f,Poll Duration %f \r\n",cpid_age,stake_age,poll_duration); - double dShareType= cdbl(GetPollXMLElementByPollTitle(Title,"",""),0); + double dShareType= RoundFromString(GetPollXMLElementByPollTitle(Title,"",""),0); // Share Type 1 == "Magnitude" // Share Type 2 == "Balance" @@ -1849,12 +1849,12 @@ Value execute(const Array& params, bool fHelp) { std::string Title = params[1].get_str(); std::string Days = params[2].get_str(); - double days = cdbl(Days,0); + double days = RoundFromString(Days,0); std::string Question = params[3].get_str(); std::string Answers = params[4].get_str(); std::string ShareType = params[5].get_str(); std::string sURL = params[6].get_str(); - double sharetype = cdbl(ShareType,0); + double sharetype = RoundFromString(ShareType,0); if (Title=="" || Question == "" || Answers == "") { entry.push_back(Pair("Error","You must specify a Poll Title, Poll Question and Poll Answers.")); @@ -2853,7 +2853,7 @@ bool PollExists(std::string pollname) bool PollExpired(std::string pollname) { std::string contract = GetPollContractByTitle("poll",pollname); - double expiration = cdbl(ExtractXML(contract,"",""),0); + double expiration = RoundFromString(ExtractXML(contract,"",""),0); return (expiration < (double)GetAdjustedTime()) ? true : false; } @@ -2862,7 +2862,7 @@ bool PollCreatedAfterSecurityUpgrade(std::string pollname) { // If the expiration is after July 1 2017, use the new security features. std::string contract = GetPollContractByTitle("poll",pollname); - double expiration = cdbl(ExtractXML(contract,"",""),0); + double expiration = RoundFromString(ExtractXML(contract,"",""),0); return (expiration > 1498867200) ? true : false; } @@ -2870,7 +2870,7 @@ bool PollCreatedAfterSecurityUpgrade(std::string pollname) double PollDuration(std::string pollname) { std::string contract = GetPollContractByTitle("poll",pollname); - double days = cdbl(ExtractXML(contract,"",""),0); + double days = RoundFromString(ExtractXML(contract,"",""),0); return days; } @@ -3102,8 +3102,8 @@ std::string GetProvableVotingWeightXML() double ReturnVerifiedVotingBalance(std::string sXML, bool bCreatedAfterSecurityUpgrade) { std::string sPayload = ExtractXML(sXML,"",""); - double dTotalVotedBalance = cdbl(ExtractXML(sPayload,"",""),2); - double dLegacyBalance = cdbl(ExtractXML(sXML,"",""),0); + double dTotalVotedBalance = RoundFromString(ExtractXML(sPayload,"",""),2); + double dLegacyBalance = RoundFromString(ExtractXML(sXML,"",""),0); if (fDebug10) printf(" \r\n Total Voted Balance %f, Legacy Balance %f \r\n",(float)dTotalVotedBalance,(float)dLegacyBalance); @@ -3122,7 +3122,7 @@ double ReturnVerifiedVotingBalance(std::string sXML, bool bCreatedAfterSecurityU std::string sXmlSig = ExtractXML(vXML[x],"",""); std::string sXmlMsg = ExtractXML(vXML[x],"",""); std::string sScriptPubKeyXml = ExtractXML(vXML[x],"",""); - int32_t iPos = cdbl(sPos,0); + int32_t iPos = RoundFromString(sPos,0); std::string sPubKey = ExtractXML(vXML[x],"",""); if (!sPubKey.empty() && !sAmt.empty() && !sPos.empty() && uTXID > 0) { @@ -3166,7 +3166,7 @@ double ReturnVerifiedVotingBalance(std::string sXML, bool bCreatedAfterSecurityU double ReturnVerifiedVotingMagnitude(std::string sXML, bool bCreatedAfterSecurityUpgrade) { - double dLegacyMagnitude = cdbl(ExtractXML(sXML,"",""),2); + double dLegacyMagnitude = RoundFromString(ExtractXML(sXML,"",""),2); if (!bCreatedAfterSecurityUpgrade) return dLegacyMagnitude; std::string sMagXML = ExtractXML(sXML,"",""); @@ -3180,7 +3180,7 @@ double ReturnVerifiedVotingMagnitude(std::string sXML, bool bCreatedAfterSecurit if (pblockindexMagnitude) { bool fResult = VerifyCPIDSignature(sXmlCPID, sXmlBlockHash, sXmlSigned); - bool fAudited = (cdbl(RoundToString(pblockindexMagnitude->nMagnitude,2),0)==cdbl(sMagnitude,0) && fResult); + bool fAudited = (RoundFromString(RoundToString(pblockindexMagnitude->nMagnitude,2),0)==RoundFromString(sMagnitude,0) && fResult); if (fAudited) return (double)pblockindexMagnitude->nMagnitude; } } @@ -3232,7 +3232,7 @@ Array GetJsonUnspentReport() bool fResult = VerifyCPIDSignature(sXmlCPID, sXmlBlockHash, sXmlSigned); entry.push_back(Pair("Historical Magnitude",pblockindexMagnitude->nMagnitude)); entry.push_back(Pair("Signature Valid",fResult)); - bool fAudited = (cdbl(RoundToString(pblockindexMagnitude->nMagnitude,2),0)==cdbl(sMagnitude,0) && fResult); + bool fAudited = (RoundFromString(RoundToString(pblockindexMagnitude->nMagnitude,2),0)==RoundFromString(sMagnitude,0) && fResult); entry.push_back(Pair("Magnitude Audited",fAudited)); results.push_back(entry); @@ -3327,7 +3327,7 @@ Array GetJsonUnspentReport() std::string sXmlMsg = ExtractXML(vXML[x],"",""); std::string sScriptPubKeyXml = ExtractXML(vXML[x],"",""); - int32_t iPos = cdbl(sPos,0); + int32_t iPos = RoundFromString(sPos,0); std::string sPubKey = ExtractXML(vXML[x],"",""); if (!sPubKey.empty() && !sAmt.empty() && !sPos.empty() && uTXID > 0) @@ -3417,7 +3417,7 @@ Array GetJsonVoteDetailsReport(std::string pollname) const std::string& GRCAddress = ExtractXML(contract,"",""); const std::string& CPID = ExtractXML(contract,"",""); - double dShareType = cdbl(GetPollXMLElementByPollTitle(Title,"",""),0); + double dShareType = RoundFromString(GetPollXMLElementByPollTitle(Title,"",""),0); std::string sShareType= GetShareType(dShareType); std::string sURL = ExtractXML(contract,"",""); @@ -3486,8 +3486,8 @@ Array GetJSONPollsReport(bool bDetail, std::string QueryByTitle, std::string& ou total_shares=0; std::string BestAnswer; double highest_share = 0; - std::string ExpirationDate = TimestampToHRDate(cdbl(Expiration,0)); - std::string sShareType = GetShareType(cdbl(ShareType,0)); + std::string ExpirationDate = TimestampToHRDate(RoundFromString(Expiration,0)); + std::string sShareType = GetShareType(RoundFromString(ShareType,0)); std::string TitleNarr = "Poll #" + RoundToString((double)iPollNumber,0) + " (" + ExpirationDate + " ) - " + sShareType; @@ -3503,7 +3503,7 @@ Array GetJSONPollsReport(bool bDetail, std::string QueryByTitle, std::string& ou for (const std::string& answer : vAnswers) { double participants=0; - double dShares = VotesCount(Title, answer, cdbl(ShareType,0),participants); + double dShares = VotesCount(Title, answer, RoundFromString(ShareType,0),participants); if (dShares > highest_share) { highest_share = dShares; @@ -3834,7 +3834,7 @@ Array MagnitudeReportCSV(bool detail) for (unsigned int i = 0; i < vCPIDTimestamps.size(); i++) { - double dTime = cdbl(vCPIDTimestamps[i],0); + double dTime = RoundFromString(vCPIDTimestamps[i],0); std::string sResearchAmount = vCPIDPayments[i]; std::string sPaymentDate = DateTimeStrFormat("%m-%d-%Y %H:%M:%S", dTime); std::string sInterestAmount = vCPIDInterestPayments[i]; @@ -4235,7 +4235,7 @@ Value listitem(const Array& params, bool fHelp) entry.push_back(Pair("Mag Out For 450",subsidy)); if (args.length() > 1) { - double myrac=cdbl(args,0); + double myrac=RoundFromString(args,0); subsidy = LederstrumpfMagnitude2(myrac, GetAdjustedTime()); entry.push_back(Pair("Mag Out",subsidy)); } @@ -4434,7 +4434,7 @@ json_spirit::Value rpc_getblockstats(const json_spirit::Array& params, bool fHel throw runtime_error( "getblockstats mode [startheight [endheight]]\n" "Show stats on what wallets and cpids staked recent blocks.\n"); - long mode= cdbl(params[0].get_str(),0); + long mode= RoundFromString(params[0].get_str(),0); (void)mode; //TODO long lowheight= 0; long highheight= INT_MAX; @@ -4443,20 +4443,20 @@ json_spirit::Value rpc_getblockstats(const json_spirit::Array& params, bool fHel { if(params.size()>=2) { - lowheight= cdbl(params[1].get_str(),0); + lowheight= RoundFromString(params[1].get_str(),0); maxblocks= INT_MAX; } if(params.size()>=3) - highheight= cdbl(params[2].get_str(),0); + highheight= RoundFromString(params[2].get_str(),0); } else if(mode==1) { /* count highheight */ maxblocks= 30000; if(params.size()>=2) - maxblocks= cdbl(params[1].get_str(),0); + maxblocks= RoundFromString(params[1].get_str(),0); if(params.size()>=3) - highheight= cdbl(params[2].get_str(),0); + highheight= RoundFromString(params[2].get_str(),0); } else throw runtime_error("getblockstats: Invalid mode specified"); CBlockIndex* cur; diff --git a/src/test/gridcoin_tests.cpp b/src/test/gridcoin_tests.cpp index 90d156b013..68f146e273 100755 --- a/src/test/gridcoin_tests.cpp +++ b/src/test/gridcoin_tests.cpp @@ -16,7 +16,7 @@ extern std::string UnpackBinarySuperblock(std::string sBlock); extern std::string ConvertHexToBin(std::string a); extern std::string ConvertBinToHex(std::string a); extern bool fTestNet; -double cdbl(std::string s, int place); +double RoundFromString(std::string s, int place); namespace { @@ -129,10 +129,5 @@ BOOST_AUTO_TEST_CASE(gridcoin_V8ShouldBeEnabledOnBlock312000InTestnet) fTestNet = was_testnet; } -BOOST_AUTO_TEST_CASE(gridcoin_cdblShouldRoundToDouble) -{ - BOOST_CHECK_EQUAL(3.14, cdbl("3.1415", 2)); -} - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index db6c7bcc54..9210a17cdf 100755 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -360,6 +360,11 @@ BOOST_AUTO_TEST_CASE(util_VerifyRoundToString) BOOST_CHECK_EQUAL("1.2346", RoundToString(1.23456789, 4)); } +BOOST_AUTO_TEST_CASE(util_RoundFromStringShouldRoundToDouble) +{ + BOOST_CHECK_EQUAL(3.14, RoundFromString("3.1415", 2)); +} + BOOST_AUTO_TEST_CASE(util_VerifySplit) { const std::string str("Hello;;My;;String;;"); diff --git a/src/util.cpp b/src/util.cpp old mode 100644 new mode 100755 index b43af441d5..7bfd820b1e --- a/src/util.cpp +++ b/src/util.cpp @@ -1462,6 +1462,11 @@ std::string RoundToString(double d, int place) return ss.str(); } +double RoundFromString(const std::string& s, int place) +{ + return Round(atof(s.c_str()), place); +} + bool Contains(const std::string& data, const std::string& instring) { return data.find(instring) != std::string::npos; diff --git a/src/util.h b/src/util.h old mode 100644 new mode 100755 index 3d7edbc22f..e85891e82b --- a/src/util.h +++ b/src/util.h @@ -200,20 +200,29 @@ void AddTimeData(const CNetAddr& ip, int64_t nTime); void runCommand(std::string strCommand); //! -//! \brief Round decimal value to N decimal places. +//! \brief Round double value to N decimal places. //! \param d Value to round. //! \param place Number of decimal places. //! double Round(double d, int place); //! -//! \brief Round a decimal value and convert it to a string. +//! \brief Round a double value and convert it to a string. //! \param d Value to round. //! \param place Number of decimal places. //! \note This always produces an output with dot as decimal separator. //! std::string RoundToString(double d, int place); +//! +//! \brief Round a double value contained in a string. +//! +//! Does \c atof on \p s and rounds the result. +//! +//! \returns \p s represented as a double rounded to \p place decimals. +//! +double RoundFromString(const std::string& s, int place); + //! //! \brief Convert any value to a string. //! \param val Value to convert. From 205279e92db4e43ea6933bbe3335dee84fe3732a Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 16 Oct 2017 10:58:02 +0200 Subject: [PATCH 044/166] Fix Qt4 incompatibilities. --- src/qt/diagnosticsdialog.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/qt/diagnosticsdialog.cpp b/src/qt/diagnosticsdialog.cpp index e5c2af01b3..c829eaa991 100644 --- a/src/qt/diagnosticsdialog.cpp +++ b/src/qt/diagnosticsdialog.cpp @@ -1,5 +1,3 @@ -#include - #include #include "main.h" #include "util.h" @@ -11,6 +9,8 @@ #include "diagnosticsdialog.h" #include "ui_diagnosticsdialog.h" +#include + std::string GetListOf(std::string datatype); double PreviousBlockAge(); @@ -273,7 +273,7 @@ void DiagnosticsDialog::on_testBtn_clicked() { } void DiagnosticsDialog::clkFinished() { - time_t ntpTime; + time_t ntpTime(0); while(udpSocket->pendingDatagramSize() != -1) { char recvBuffer[udpSocket->pendingDatagramSize()]; @@ -313,6 +313,11 @@ void DiagnosticsDialog::TCPFailed(QAbstractSocket::SocketError socket) { } void DiagnosticsDialog::getGithubVersionFinished(QNetworkReply *reply) { + // Qt didn't get JSON support until 5.x. Ignore version checks when using + // Qt4 an drop this condition once we drop Qt4 support. +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + ui->checkClientVersionResultLbl->setText("N/A"); +#else QByteArray data; data = reply->readAll(); std::string newVersionString; @@ -354,4 +359,5 @@ void DiagnosticsDialog::getGithubVersionFinished(QNetworkReply *reply) { } else ui->checkClientVersionResultLbl->setText("Up to date"); } +#endif } From 8da4a7061cb586dde51ab1ba56969ff0707d65c4 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 17 Oct 2017 08:41:00 +0200 Subject: [PATCH 045/166] Move appcache implementations to appcache.cpp. --- gridcoinresearch.pro | 3 ++- src/Makefile.include.objs | 3 ++- src/appcache.cpp | 24 ++++++++++++++++++++++++ src/appcache.h | 20 +++----------------- 4 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 src/appcache.cpp diff --git a/gridcoinresearch.pro b/gridcoinresearch.pro index 156b4ee142..e502a72df7 100755 --- a/gridcoinresearch.pro +++ b/gridcoinresearch.pro @@ -352,7 +352,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/upgrader.cpp \ src/boinc.cpp \ src/allocators.cpp \ - src/backup.cpp + src/backup.cpp \ + src/appcache.cpp ## #RC_FILE = qaxserver.rc diff --git a/src/Makefile.include.objs b/src/Makefile.include.objs index b69c0217b8..dd643edb8f 100755 --- a/src/Makefile.include.objs +++ b/src/Makefile.include.objs @@ -38,4 +38,5 @@ OBJS= \ obj/beacon.o \ obj/boinc.o \ obj/allocators.o \ - obj/backup.o + obj/backup.o \ + obj/appcache.o diff --git a/src/appcache.cpp b/src/appcache.cpp new file mode 100644 index 0000000000..7c69d42c6b --- /dev/null +++ b/src/appcache.cpp @@ -0,0 +1,24 @@ +#include "appcache.h" + +// TODO: Remove this include when mvApplicationCache has moved to this file. +#include "main.h" + +// Predicate +AppCacheMatches::AppCacheMatches(const std::string& needle) + : needle(needle) +{} + +bool AppCacheMatches::operator()(const AppCache::value_type& t) +{ + return boost::algorithm::starts_with(t.first, needle); +} + +// Filter +boost::iterator_range AppCacheFilter(const std::string& needle) +{ + auto pred = AppCacheMatches(needle); + auto begin = boost::make_filter_iterator(pred, mvApplicationCache.begin(), mvApplicationCache.end()); + auto end = boost::make_filter_iterator(pred, mvApplicationCache.end(), mvApplicationCache.end()); + return boost::make_iterator_range(begin, end); +} + diff --git a/src/appcache.h b/src/appcache.h index 9dbc421e71..c0348fb3e2 100644 --- a/src/appcache.h +++ b/src/appcache.h @@ -13,15 +13,8 @@ typedef std::map AppCache; // Predicate struct AppCacheMatches { - AppCacheMatches(const std::string& needle) - : needle(needle) - {} - - bool operator()(const AppCache::value_type& t) - { - return boost::algorithm::starts_with(t.first, needle); - }; - + AppCacheMatches(const std::string& needle); + bool operator()(const AppCache::value_type& t); std::string needle; }; @@ -41,11 +34,4 @@ typedef boost::filter_iterator filter_itera //! } //! \endcode //! -boost::iterator_range AppCacheFilter(const std::string& needle) -{ - auto pred = AppCacheMatches(needle); - auto begin = boost::make_filter_iterator(pred, mvApplicationCache.begin(), mvApplicationCache.end()); - auto end = boost::make_filter_iterator(pred, mvApplicationCache.end(), mvApplicationCache.end()); - return boost::make_iterator_range(begin, end); -} - +boost::iterator_range AppCacheFilter(const std::string& needle); From 5eb0f49c0576063c095fd562d741be2570021600 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 17 Oct 2017 08:42:31 +0200 Subject: [PATCH 046/166] Move boost include to source. --- src/appcache.cpp | 2 ++ src/appcache.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/appcache.cpp b/src/appcache.cpp index 7c69d42c6b..ba2c0e4192 100644 --- a/src/appcache.cpp +++ b/src/appcache.cpp @@ -3,6 +3,8 @@ // TODO: Remove this include when mvApplicationCache has moved to this file. #include "main.h" +#include + // Predicate AppCacheMatches::AppCacheMatches(const std::string& needle) : needle(needle) diff --git a/src/appcache.h b/src/appcache.h index c0348fb3e2..9f86b0f493 100644 --- a/src/appcache.h +++ b/src/appcache.h @@ -2,7 +2,6 @@ #include #include -#include #include //! From 77b7a64c486bcfa5c5b571c800cd3e272f1e8c73 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 17 Oct 2017 09:20:42 +0200 Subject: [PATCH 047/166] Fix build error. --- src/appcache.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/appcache.h b/src/appcache.h index 9f86b0f493..beb7b8d4c2 100644 --- a/src/appcache.h +++ b/src/appcache.h @@ -3,6 +3,7 @@ #include #include #include +#include //! //! \brief Application cache type. From 8aac8d16bc9441d521603cad9f7723283091fd5f Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Wed, 18 Oct 2017 07:42:49 +0200 Subject: [PATCH 048/166] Do not use iterator_fwd as it seems to break Travis. --- src/appcache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/appcache.h b/src/appcache.h index beb7b8d4c2..250a4c3d0d 100644 --- a/src/appcache.h +++ b/src/appcache.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include //! //! \brief Application cache type. From 2335820b05b9ce1e11dd78683b153bf5ff0f98a3 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 21 Oct 2017 07:58:27 +0200 Subject: [PATCH 049/166] Clean up GetNeuralNetworkSupermajorityHash. --- src/main.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 73baa87ed3..09ee647d6e 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -8114,17 +8114,24 @@ void IncrementVersionCount(const std::string& Version) std::string GetNeuralNetworkSupermajorityHash(double& out_popularity) { double highest_popularity = -1; - std::string neural_hash = ""; - for(map::iterator ii=mvNeuralNetworkHash.begin(); ii!=mvNeuralNetworkHash.end(); ++ii) + std::string neural_hash; + + for(const auto& network_hash : mvNeuralNetworkHash) { - double popularity = mvNeuralNetworkHash[(*ii).first]; - // d41d8 is the hash of an empty magnitude contract - don't count it - if ( ((*ii).first != "d41d8cd98f00b204e9800998ecf8427e") && popularity > 0 && popularity > highest_popularity && (*ii).first != "TOTAL_VOTES") - { - highest_popularity = popularity; - neural_hash = (*ii).first; - } + const std::string& hash = network_hash.first; + double popularity = network_hash.second; + + // d41d8 is the hash of an empty magnitude contract - don't count it + if (popularity > 0 && + popularity > highest_popularity && + hash != "d41d8cd98f00b204e9800998ecf8427e" && + hash != "TOTAL_VOTES") + { + highest_popularity = popularity; + neural_hash = hash; + } } + out_popularity = highest_popularity; return neural_hash; } From a2d9f5c1c8863ba10902b12fd8b9aa17a948c05a Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 21 Oct 2017 08:20:07 +0200 Subject: [PATCH 050/166] Reduce depth of AddResearchMagnitude. --- src/main.cpp | 67 ++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 09ee647d6e..7ee9317a71 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5266,45 +5266,40 @@ void AdjustTimestamps(StructCPID& strCPID, double timestamp, double subsidy) void AddResearchMagnitude(CBlockIndex* pIndex) { - // Headless critical section - if (pIndex->nResearchSubsidy > 0) + if (pIndex->nResearchSubsidy <= 0) + return; + + try { - try - { - StructCPID stMag = GetInitializedStructCPID2(pIndex->GetCPID(),mvMagnitudesCopy); - stMag.cpid = pIndex->GetCPID(); - stMag.GRCAddress = pIndex->sGRCAddress; - if (pIndex->nHeight > stMag.LastBlock) - { - stMag.LastBlock = pIndex->nHeight; - } - stMag.entries++; - stMag.payments += pIndex->nResearchSubsidy; - stMag.interestPayments += pIndex->nInterestSubsidy; - - AdjustTimestamps(stMag,pIndex->nTime, pIndex->nResearchSubsidy); - // Track detailed payments made to each CPID - stMag.PaymentTimestamps += ToString(pIndex->nTime) + ","; - stMag.PaymentAmountsResearch += RoundToString(pIndex->nResearchSubsidy,2) + ","; - stMag.PaymentAmountsInterest += RoundToString(pIndex->nInterestSubsidy,2) + ","; - stMag.PaymentAmountsBlocks += ToString(pIndex->nHeight) + ","; - stMag.Accuracy++; - stMag.AverageRAC = stMag.rac / (stMag.entries+.01); - double total_owed = 0; - stMag.owed = GetOutstandingAmountOwed(stMag, - pIndex->GetCPID(), pIndex->nTime, total_owed, pIndex->nMagnitude); - - stMag.totalowed = total_owed; - mvMagnitudesCopy[pIndex->GetCPID()] = stMag; - } - catch (const std::bad_alloc& ba) + StructCPID stMag = GetInitializedStructCPID2(pIndex->GetCPID(),mvMagnitudesCopy); + stMag.cpid = pIndex->GetCPID(); + stMag.GRCAddress = pIndex->sGRCAddress; + if (pIndex->nHeight > stMag.LastBlock) { - printf("\r\nBad Allocation in AddResearchMagnitude() \r\n"); - } - catch(...) - { - printf("Exception in AddResearchMagnitude() \r\n"); + stMag.LastBlock = pIndex->nHeight; } + stMag.entries++; + stMag.payments += pIndex->nResearchSubsidy; + stMag.interestPayments += pIndex->nInterestSubsidy; + + AdjustTimestamps(stMag,pIndex->nTime, pIndex->nResearchSubsidy); + // Track detailed payments made to each CPID + stMag.PaymentTimestamps += ToString(pIndex->nTime) + ","; + stMag.PaymentAmountsResearch += RoundToString(pIndex->nResearchSubsidy,2) + ","; + stMag.PaymentAmountsInterest += RoundToString(pIndex->nInterestSubsidy,2) + ","; + stMag.PaymentAmountsBlocks += ToString(pIndex->nHeight) + ","; + stMag.Accuracy++; + stMag.AverageRAC = stMag.rac / (stMag.entries+.01); + double total_owed = 0; + stMag.owed = GetOutstandingAmountOwed(stMag, + pIndex->GetCPID(), pIndex->nTime, total_owed, pIndex->nMagnitude); + + stMag.totalowed = total_owed; + mvMagnitudesCopy[pIndex->GetCPID()] = stMag; + } + catch (const std::bad_alloc& ba) + { + printf("\r\nBad Allocation in AddResearchMagnitude() \r\n"); } } From 0c56e096c3b0794eccb263201729267c5e3d176e Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 21 Oct 2017 09:42:52 +0200 Subject: [PATCH 051/166] Fix problems with hanging threads while shutting down. --- src/bitcoinrpc.cpp | 24 +++++++++++++++++++----- src/bitcoinrpc.h | 2 +- src/init.cpp | 2 ++ src/qt/bitcoin.cpp | 1 + 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 121ed1b830..dde1e81b56 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -35,6 +35,9 @@ void ThreadRPCServer2(void* parg); static std::string strRPCUserColonPass; +// These are created by StartRPCThreads, destroyed in StopRPCThreads +static asio::io_service* rpc_io_service = NULL; + const Object emptyobj; void ThreadRPCServer3(void* parg); @@ -664,6 +667,16 @@ class AcceptedConnectionImpl : public AcceptedConnection iostreams::stream< SSLIOStreamDevice > _stream; }; +void StopRPCThreads() +{ + if(!rpc_io_service) + return; + + rpc_io_service->stop(); + delete rpc_io_service; + rpc_io_service = NULL; +} + void ThreadRPCServer(void* parg) { // Make this thread recognisable as the RPC listener @@ -797,9 +810,10 @@ void ThreadRPCServer2(void* parg) const bool fUseSSL = GetBoolArg("-rpcssl"); - asio::io_service io_service; + assert(rpc_io_service == NULL); + rpc_io_service = new asio::io_service(); - ssl::context context(io_service, ssl::context::sslv23); + ssl::context context(*rpc_io_service, ssl::context::sslv23); if (fUseSSL) { context.set_options(ssl::context::no_sslv2); @@ -823,7 +837,7 @@ void ThreadRPCServer2(void* parg) asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any(); ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", GetDefaultRPCPort())); boost::system::error_code v6_only_error; - boost::shared_ptr acceptor(new ip::tcp::acceptor(io_service)); + boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); boost::signals2::signal StopRequests; @@ -860,7 +874,7 @@ void ThreadRPCServer2(void* parg) bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any(); endpoint.address(bindAddress); - acceptor.reset(new ip::tcp::acceptor(io_service)); + acceptor.reset(new ip::tcp::acceptor(*rpc_io_service)); acceptor->open(endpoint.protocol()); acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); acceptor->bind(endpoint); @@ -887,7 +901,7 @@ void ThreadRPCServer2(void* parg) } while (!fShutdown) - io_service.run_one(); + rpc_io_service->run_one(); StopRequests(); } diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index afbac34db3..2421b84264 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -69,6 +69,7 @@ enum RPCErrorCode json_spirit::Object JSONRPCError(int code, const std::string& message); +void StopRPCThreads(); void ThreadRPCServer(void* parg); int CommandLineRPC(int argc, char *argv[]); @@ -139,7 +140,6 @@ extern void EnsureWalletIsUnlocked(); extern uint256 ParseHashV(const json_spirit::Value& v, std::string strName); extern uint256 ParseHashO(const json_spirit::Object& o, std::string strKey); extern std::vector ParseHexV(const json_spirit::Value& v, std::string strName); -extern std::vector ParseHexO(const json_spirit::Object& o, std::string strKey); extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); diff --git a/src/init.cpp b/src/init.cpp index c6efc137c5..28d421db62 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -151,6 +151,7 @@ void Shutdown(void* parg) bitdb.Flush(false); StopNode(); bitdb.Flush(true); + StopRPCThreads(); boost::filesystem::remove(GetPidFile()); UnregisterWallet(pwalletMain); delete pwalletMain; @@ -254,6 +255,7 @@ bool AppInit(int argc, char* argv[]) Shutdown(NULL); // delete thread handler + threads->interruptAll(); threads->removeAll(); threads.reset(); diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 5dd9ee7dbe..72814c3f96 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -335,6 +335,7 @@ int main(int argc, char *argv[]) } // delete thread handler + threads->interruptAll(); threads->removeAll(); threads.reset(); From 347ad16d7d2798ae2b4f59f1d48552baa822cb98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sat, 21 Oct 2017 14:09:16 +0200 Subject: [PATCH 052/166] Enable Beaconchecks on blocks after V9. #524 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 7ee9317a71..2d9735f677 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3976,7 +3976,7 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh return DoS(50, error("CheckBlock[] : block timestamp earlier than transaction timestamp")); // Verify beacon contract if a transaction contains a beacon contract - if (!VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) + if ( nVersion>=9 && !VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) return DoS(25, error("CheckBlock[] : bad beacon contract found in tx contained within block; rejected")); } From 5ce555a2026bf927627a4948d90c7ee783d1bfa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sat, 21 Oct 2017 14:09:57 +0200 Subject: [PATCH 053/166] Emulate old behaviour of ClearCache for blocks belov v9. #577 --- src/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 2d9735f677..6d95b4341e 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5502,7 +5502,12 @@ bool ComputeNeuralNetworkSupermajorityHashes() if (mvCurrentNeuralNetworkHash.size() > 0) mvCurrentNeuralNetworkHash.clear(); //Clear the votes - ClearCache("neuralsecurity"); + /* ClearCache was no-op in previous version due to bug. Now it was fixed, + but we have to emulate the old behaviour to prevent early forks. */ + if(pindexBest && pindexBest->nVersion>=9) + { + ClearCache("neuralsecurity"); + } WriteCache("neuralsecurity","pending","0",GetAdjustedTime()); try { From 840fcd36916b0ea2acc1be5b0248e4d11d3a9a79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sat, 21 Oct 2017 14:11:46 +0200 Subject: [PATCH 054/166] Use different prefix to store contract TrxIDs and only in debug mode. #683 --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 6d95b4341e..7810885129 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -8293,7 +8293,8 @@ bool MemorizeMessage(const CTransaction &tx, double dAmount, std::string sRecipi fMessageLoaded = true; } - WriteCache(sMessageType,sMessageKey+";TrxID",tx.GetHash().GetHex(),nTime); + if(fDebug) + WriteCache("TrxID;"+sMessageType,sMessageKey,tx.GetHash().GetHex(),nTime); } From 44c9445f2e5c53b8b719964c8ef9b95a11c44c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sat, 21 Oct 2017 14:12:35 +0200 Subject: [PATCH 055/166] Fix newbie stake reward. #552 Use proper magnitude unit. Prevent newbie reward when previous stake had zero mag. Effective after v9. --- src/main.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7810885129..440d7598c7 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -8438,10 +8438,21 @@ int64_t ComputeResearchAccrual(int64_t nTime, std::string cpid, std::string oper { double dCurrentMagnitude = CalculatedMagnitude2(cpid, nTime, false); if(fDebug && !bVerifyingBlock) printf("ComputeResearchAccrual.CRE.Begin: cpid=%s {%s %d} (best %d)\n",cpid.c_str(),pindexLast->GetBlockHash().GetHex().c_str(),pindexLast->nHeight,pindexBest->nHeight); + if(pindexLast->nVersion>=9) + { + // Bugfix for newbie rewards always being around 1 GRC + dMagnitudeUnit = GRCMagnitudeUnit(nTime); + } if(fDebug && !bVerifyingBlock) printf("CRE: dCurrentMagnitude= %.1f in.dMagnitudeUnit= %f\n",dCurrentMagnitude,dMagnitudeUnit); CBlockIndex* pHistorical = GetHistoricalMagnitude(cpid); if(fDebug && !bVerifyingBlock) printf("CRE: pHistorical {%s %d} hasNext= %d nMagnitude= %.1f\n",pHistorical->GetBlockHash().GetHex().c_str(),pHistorical->nHeight,!!pHistorical->pnext,pHistorical->nMagnitude); - if (pHistorical->nHeight <= nNewIndex || pHistorical->nMagnitude==0 || pHistorical->nTime == 0) + bool bIsNewbie = (pHistorical->nHeight <= nNewIndex || pHistorical->nTime==0); + if(pindexLast->nVersion<9) + { + // Bugfix for zero mag stakes being mistaken for newbie stake + bIsNewbie |= pHistorical->nMagnitude==0; + } + if (bIsNewbie) { //No prior block exists... Newbies get .01 age to bootstrap the CPID (otherwise they will not have any prior block to refer to, thus cannot get started): if(fDebug && !bVerifyingBlock) printf("CRE: No prior block exists...\n"); @@ -8473,7 +8484,7 @@ int64_t ComputeResearchAccrual(int64_t nTime, std::string cpid, std::string oper } else { - if(fDebug && !bVerifyingBlock) printf("CRE: Using 0.01 age bootstrap\n"); + if(fDebug && !bVerifyingBlock) printf("CRE: Invalid Beacon, Using 0.01 age bootstrap\n"); return dCurrentMagnitude > 0 ? (((dCurrentMagnitude/100)*COIN) + (1*COIN)): 0; } } From 40444b73ca168782552ec9ea35aa0cf61f29df85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sat, 21 Oct 2017 14:27:23 +0200 Subject: [PATCH 056/166] Prevent duplicate superblocks in v9. (#534) --- src/main.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 440d7598c7..1fb86848b5 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4235,10 +4235,24 @@ bool NeedASuperblock() GetSuperblockProjectCount(superblock, out_project_count, out_whitelist_count); */ } + int64_t superblock_age = GetAdjustedTime() - mvApplicationCacheTimestamp["superblock;magnitudes"]; if (superblock_age > GetSuperblockAgeSpacing(nBestHeight)) bDireNeedOfSuperblock = true; + if(bDireNeedOfSuperblock && pindexBest && pindexBest->nVersion>=9) + { + // If all the checks indicate true and is v9, look 15 blocks back to + // prevent duplicate superblocks + for(CBlockIndex *pindex = pindexBest; + pindex && pindex->nHeight + 15 > nBestHeight; + pindex = pindex->pprev) + { + if(pindex->nIsSuperBlock) + return false; + } + } + return bDireNeedOfSuperblock; } From 76c05f99ad7872c03e6b7f1c17095cc7e1bb61ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sat, 21 Oct 2017 14:08:24 +0200 Subject: [PATCH 057/166] Foundation for Block Version 9 --- src/main.cpp | 5 ++++- src/main.h | 9 ++++++++- src/miner.cpp | 4 +++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1fb86848b5..84a4399526 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4028,10 +4028,13 @@ bool CBlock::AcceptBlock(bool generated_by_me) // The block height at which point we start rejecting v7 blocks and // start accepting v8 blocks. if( (IsProtocolV2(nHeight) && nVersion < 7) - || (IsV8Enabled(nHeight) && nVersion < 8)) + || (IsV8Enabled(nHeight) && nVersion < 8) + || (IsV9Enabled(nHeight) && nVersion < 9) + ) return DoS(20, error("AcceptBlock() : reject too old nVersion = %d", nVersion)); else if( (!IsProtocolV2(nHeight) && nVersion >= 7) ||(!IsV8Enabled(nHeight) && nVersion >= 8) + ||(!IsV9Enabled(nHeight) && nVersion >= 9) ) return DoS(100, error("AcceptBlock() : reject too new nVersion = %d", nVersion)); diff --git a/src/main.h b/src/main.h index 2586dca6d3..d89409b693 100755 --- a/src/main.h +++ b/src/main.h @@ -96,6 +96,13 @@ inline uint32_t IsV8Enabled(int nHeight) : nHeight > 1010000; } +inline uint32_t IsV9Enabled(int nHeight) +{ + return fTestNet + ? nHeight >= 378600 + : nHeight >= 2000000; +} + inline int GetSuperblockAgeSpacing(int nHeight) { return (fTestNet ? 86400 : (nHeight > 364500) ? 86400 : 43200); @@ -976,7 +983,7 @@ class CBlock { public: // header - static const int CURRENT_VERSION = 8; + static const int CURRENT_VERSION = 9; int nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; diff --git a/src/miner.cpp b/src/miner.cpp index b2c022ab83..3c5747ec2a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -845,10 +845,12 @@ void StakeMiner(CWallet *pwallet) MinerStatus.Message=""; MinerStatus.ReasonNotStaking=""; - //New version + //New versions StakeBlock.nVersion = 7; if(IsV8Enabled(pindexPrev->nHeight+1)) StakeBlock.nVersion = 8; + if(IsV9Enabled(pindexPrev->nHeight+1)) + StakeBlock.nVersion = 9; MinerStatus.Version= StakeBlock.nVersion; } From 906c301d56ccb62eac7a38a23f920eb38b472d04 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 16:03:29 -0700 Subject: [PATCH 058/166] Fix for beaconchecks issues + more debug messages --- src/beacon.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/beacon.cpp b/src/beacon.cpp index 8053c411d3..c660d45042 100755 --- a/src/beacon.cpp +++ b/src/beacon.cpp @@ -138,41 +138,82 @@ std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxS bool VerifyBeaconContractTx(const std::string& txhashBoinc) { + // Mandatory block needed. + // Current bad contracts in chain would cause a fork on sync + // Previous beacons in the past have 3 elements not 4 thus causing empty contract elements as coded in GetBeaconElements + if ( + (fTestNet && nBestHeight <= 300000) + || (!fTestNet && nBestHeight <= 1070000) + ) + return true; // allow sync from 0 till these blocks when this check comes into effect + // Check if tx contains beacon advertisement and evaluate for certain conditions std::string chkMessageType = ExtractXML(txhashBoinc, "", ""); std::string chkMessageAction = ExtractXML(txhashBoinc, "", ""); - if (chkMessageAction != "A" && chkMessageType != "beacon") + + if (chkMessageType != "beacon") return true; // Not beacon contract + + if (chkMessageAction != "A") + return true; // Not an add contract for beacon + std::string chkMessageContract = ExtractXML(txhashBoinc, "", ""); std::string chkMessageContractCPID = ExtractXML(txhashBoinc, "", ""); // Here we GetBeaconElements for the contract in the tx std::string tx_out_cpid; std::string tx_out_address; std::string tx_out_publickey; + GetBeaconElements(chkMessageContract, tx_out_cpid, tx_out_address, tx_out_publickey); - if (tx_out_cpid == "" || tx_out_address == "" || tx_out_publickey == "" || chkMessageContractCPID == "") - return false; + + if (tx_out_cpid.empty() || tx_out_address.empty() || tx_out_publickey.empty() || chkMessageContractCPID.empty()) + return false; // Incomplete contract + std::string chkKey = "beacon;" + chkMessageContractCPID; std::string chkValue = mvApplicationCache[chkKey]; + + if (chkValue.empty()) + { + if (fDebug10) + printf("VBCTX : No Previous beacon found for CPID %s\n", chkMessageContractCPID.c_str()); + + return true; // No previous beacon in cache + } + int64_t chkiAge = pindexBest != NULL ? pindexBest->nTime - mvApplicationCacheTimestamp[chkKey] : 0; int64_t chkSecondsBase = 60 * 24 * 30 * 60; + // Conditions // Condition a) if beacon is younger then 5 months deny tx if (chkiAge <= chkSecondsBase * 5 && chkiAge >= 1) + { + if (fDebug10) + printf("VBCTX : Beacon age violation. Beacon Age %" PRId64 " < Required Age %" PRId64 "\n", chkiAge, (chkSecondsBase * 5)); + return false; + } + // Condition b) if beacon is younger then 6 months but older then 5 months verify using the same keypair; if not deny tx if (chkiAge >= chkSecondsBase * 5 && chkiAge <= chkSecondsBase * 6) { std::string chk_out_cpid; std::string chk_out_address; std::string chk_out_publickey; + // Here we GetBeaconElements for the contract in the current beacon in chain GetBeaconElements(chkValue, chk_out_cpid, chk_out_address, chk_out_publickey); + if (tx_out_publickey != chk_out_publickey) + { + if (fDebug10) + printf("VBCTX : Beacon tx publickey != publickey in chain. %s != %s\n", tx_out_publickey.c_str(), chk_out_publickey.c_str()); + return false; + } } + // Passed checks return true; } From ec336ca7654cef10ed606c9fb653ed0ababfbca7 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 16:07:12 -0700 Subject: [PATCH 059/166] Fix for testnet start block --- src/beacon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/beacon.cpp b/src/beacon.cpp index c660d45042..4b42c09de3 100755 --- a/src/beacon.cpp +++ b/src/beacon.cpp @@ -142,7 +142,7 @@ bool VerifyBeaconContractTx(const std::string& txhashBoinc) // Current bad contracts in chain would cause a fork on sync // Previous beacons in the past have 3 elements not 4 thus causing empty contract elements as coded in GetBeaconElements if ( - (fTestNet && nBestHeight <= 300000) + (fTestNet && nBestHeight <= 378000) || (!fTestNet && nBestHeight <= 1070000) ) return true; // allow sync from 0 till these blocks when this check comes into effect From 317c360ba47b3ee8a3760017dec773b909c23b7c Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 16:09:02 -0700 Subject: [PATCH 060/166] add more debug to memorypool check and checkblock --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7ee9317a71..3b7454432c 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1399,7 +1399,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool* pfMissingInput // Verify beacon contract in tx if found if (!VerifyBeaconContractTx(tx.hashBoinc)) - return tx.DoS(25, error("AcceptToMemoryPool : bad beacon contract in tx; rejected")); + return tx.DoS(25, error("AcceptToMemoryPool : bad beacon contract in tx %s; rejected", tx.GetHash().ToString().c_str())); // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) @@ -3977,7 +3977,7 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh // Verify beacon contract if a transaction contains a beacon contract if (!VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) - return DoS(25, error("CheckBlock[] : bad beacon contract found in tx contained within block; rejected")); + return DoS(25, error("CheckBlock[] : bad beacon contract found in tx %s contained within block; rejected", tx.GetHash().ToString().c_str())); } // Check for duplicate txids. This is caught by ConnectInputs(), From 8b0c49b3736c544aad93574cff549b7d08917626 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 13:12:55 -0700 Subject: [PATCH 061/166] changes --- src/init.cpp | 58 ----------------------- src/main.cpp | 50 +++++++++++--------- src/rpcblockchain.cpp | 105 ++++++++---------------------------------- 3 files changed, 48 insertions(+), 165 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 28d421db62..144f6bb80f 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -29,8 +29,6 @@ void BusyWaitForTally(); void LoadCPIDsInBackground(); bool IsConfigFileEmpty(); -std::string ToOfficialName(std::string proj); - #ifndef WIN32 #include #endif @@ -45,8 +43,6 @@ extern unsigned int nNodeLifespan; extern unsigned int nDerivationMethodIndex; extern unsigned int nMinerSleep; extern bool fUseFastIndex; -void InitializeBoincProjects(); - ////////////////////////////////////////////////////////////////////////////// // @@ -72,58 +68,6 @@ void StartShutdown() #endif } -void InitializeBoincProjects() -{ - //Initialize GlobalCPUMiningCPID - GlobalCPUMiningCPID.initialized = true; - GlobalCPUMiningCPID.cpid=""; - GlobalCPUMiningCPID.cpidv2 = ""; - GlobalCPUMiningCPID.projectname =""; - GlobalCPUMiningCPID.rac=0; - GlobalCPUMiningCPID.encboincpublickey = ""; - GlobalCPUMiningCPID.boincruntimepublickey = ""; - GlobalCPUMiningCPID.pobdifficulty = 0; - GlobalCPUMiningCPID.diffbytes = 0; - GlobalCPUMiningCPID.email = ""; - GlobalCPUMiningCPID.RSAWeight = 0; - - //Loop through projects saved in the Gridcoin Persisted Data System - std::string sType = "project"; - for(map::iterator ii=mvApplicationCache.begin(); ii!=mvApplicationCache.end(); ++ii) - { - std::string key_name = (*ii).first; - if (key_name.length() > sType.length()) - { - if (key_name.substr(0,sType.length())==sType) - { - std::string key_value = mvApplicationCache[(*ii).first]; - std::vector vKey = split(key_name,";"); - if (vKey.size() > 0) - { - - std::string project_name = vKey[1]; - printf("Proj %s ",project_name.c_str()); - std::string project_value = key_value; - boost::to_lower(project_name); - std::string mainProject = ToOfficialName(project_name); - boost::to_lower(mainProject); - StructCPID structcpid = GetStructCPID(); - mvBoincProjects.insert(map::value_type(mainProject,structcpid)); - structcpid = mvBoincProjects[mainProject]; - structcpid.initialized = true; - structcpid.link = "http://"; - structcpid.projectname = mainProject; - mvBoincProjects[mainProject] = structcpid; - WHITELISTED_PROJECTS++; - - } - } - } - } - -} - - void Shutdown(void* parg) { static CCriticalSection cs_Shutdown; @@ -1024,8 +968,6 @@ bool AppInit2(ThreadHandlerPtr threads) LoadAdminMessages(true,sOut); printf("Done loading Admin messages"); - InitializeBoincProjects(); - printf("Done loading boinc projects"); uiInterface.InitMessage(_("Compute Neural Network Hashes...")); ComputeNeuralNetworkSupermajorityHashes(); diff --git a/src/main.cpp b/src/main.cpp index 7ee9317a71..e1f3628404 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,6 +22,7 @@ #include "beacon.h" #include "miner.h" #include "backup.h" +#include "appcache.h" #include #include @@ -277,7 +278,6 @@ bool bGridcoinGUILoaded = false; extern double LederstrumpfMagnitude2(double Magnitude, int64_t locktime); extern void WriteAppCache(std::string key, std::string value); -extern std::string AppCache(std::string key); extern void LoadCPIDsInBackground(); extern void ThreadCPIDs(); @@ -349,7 +349,6 @@ std::map mvNetworkCopy; //Contains the project sta std::map mvCreditNodeCPID; // Contains verified CPID Magnitudes; std::map mvCPIDCache; //Contains cached blocknumbers for CPID+Projects; std::map mvAppCache; //Contains cached blocknumbers for CPID+Projects; -std::map mvBoincProjects; // Contains all of the allowed boinc projects; std::map mvMagnitudes; // Contains Magnitudes by CPID & Outstanding Payments Owed per CPID std::map mvMagnitudesCopy; // Contains Magnitudes by CPID & Outstanding Payments Owed per CPID @@ -555,19 +554,19 @@ void GetGlobalStatus() -std::string AppCache(std::string key) -{ - - StructCPIDCache setting = mvAppCache["cache"+key]; - if (!setting.initialized) - { - setting.initialized=true; - setting.xml = ""; - mvAppCache.insert(map::value_type("cache"+key,setting)); - mvAppCache["cache"+key]=setting; - } - return setting.xml; -} +//std::string AppCache(std::string key) +//{ +// +// StructCPIDCache setting = mvAppCache["cache"+key]; +// if (!setting.initialized) +// { +// setting.initialized=true; +// setting.xml = ""; +// mvAppCache.insert(map::value_type("cache"+key,setting)); +// mvAppCache["cache"+key]=setting; +// } +// return setting.xml; +//} @@ -7330,15 +7329,24 @@ void InitializeProjectStruct(StructCPID& project) } - -bool ProjectIsValid(std::string project) +bool ProjectIsValid(std::string sProject) { - boost::to_lower(project); + if (sProject.empty()) + return false; - StructCPID structcpid = GetInitializedStructCPID2(project,mvBoincProjects); + boost::to_lower(sProject); - return structcpid.initialized; + for (const auto& item : AppCacheFilter("project")) + { + std::string sProjectKey = item.first; + std::vector vProjectKey = split(sProjectKey, ";"); + std::string sProjectName = ToOfficialName(vProjectKey[1]); + if (sProjectName == sProject) + return true; + } + + return false; } std::string ToOfficialName(std::string proj) @@ -8288,7 +8296,7 @@ bool MemorizeMessage(const CTransaction &tx, double dAmount, std::string sRecipi fMessageLoaded = true; } - WriteCache(sMessageType,sMessageKey+";TrxID",tx.GetHash().GetHex(),nTime); + //WriteCache(sMessageType,sMessageKey+";TrxID",tx.GetHash().GetHex(),nTime); } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 8933b13d1d..3b11966f6d 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -21,6 +21,7 @@ #include // for to_lower() #include #include +#include using namespace json_spirit; using namespace std; @@ -150,6 +151,8 @@ std::string RetrieveMd5(std::string s1); std::string getfilecontents(std::string filename); +std::string ToOfficialName(std::string proj); + extern double GetNetworkAvgByProject(std::string projectname); void HarvestCPIDs(bool cleardata); void ExecuteCode(); @@ -4011,94 +4014,22 @@ Value listitem(const Array& params, bool fHelp) else if (sitem == "explainmagnitude") { + Object entry; if (msNeuralResponse.length() > 25) { - Object entry; std::vector vMag = split(msNeuralResponse.c_str(),""); for (unsigned int i = 0; i < vMag.size(); i++) { entry.push_back(Pair(RoundToString(i+1,0),vMag[i].c_str())); } - results.push_back(entry); } - else - { - - double mytotalrac = 0; - double nettotalrac = 0; - double projpct = 0; - double mytotalpct = 0; - double ParticipatingProjectCount = 0; - double TotalMagnitude = 0; - double Mag = 0; - Object entry; - std::string narr = ""; - std::string narr_desc = ""; - double TotalProjectRAC = 0; - double TotalUserVerifiedRAC = 0; - for(map::iterator ibp=mvBoincProjects.begin(); ibp!=mvBoincProjects.end(); ++ibp) + else { - StructCPID WhitelistedProject = mvBoincProjects[(*ibp).first]; - if (WhitelistedProject.initialized) - { - double ProjectRAC = GetNetworkTotalByProject(WhitelistedProject.projectname); - StructCPID structcpid = mvCPIDs[WhitelistedProject.projectname]; - bool including = false; - narr = ""; - narr_desc = ""; - double UserVerifiedRAC = 0; - if (structcpid.initialized) - { - if (structcpid.projectname.length() > 1) - { - including = (ProjectRAC > 0 && structcpid.Iscpidvalid && structcpid.rac > 1); - UserVerifiedRAC = structcpid.rac; - narr_desc = "NetRac: " + RoundToString(ProjectRAC,0) + ", CPIDValid: " - + YesNo(structcpid.Iscpidvalid) + ", RAC: " +RoundToString(structcpid.rac,0); - } - } - narr = including ? ("Participating " + narr_desc) : ("Enumerating " + narr_desc); - if (structcpid.projectname.length() > 1 && including) - { - entry.push_back(Pair(narr + " Project",structcpid.projectname)); - } - - projpct = UserVerifiedRAC/(ProjectRAC+.01); - nettotalrac += ProjectRAC; - mytotalrac = mytotalrac + UserVerifiedRAC; - mytotalpct = mytotalpct + projpct; - - double project_magnitude = - ((UserVerifiedRAC / (ProjectRAC + 0.01)) / (WHITELISTED_PROJECTS + 0.01)) * NeuralNetworkMultiplier; - - if (including) - { - TotalMagnitude += project_magnitude; - TotalUserVerifiedRAC += UserVerifiedRAC; - TotalProjectRAC += ProjectRAC; - ParticipatingProjectCount++; - - entry.push_back(Pair("User " + structcpid.projectname + " Verified RAC",UserVerifiedRAC)); - entry.push_back(Pair(structcpid.projectname + " Network RAC",ProjectRAC)); - entry.push_back(Pair("Your Project Magnitude",project_magnitude)); - } - - } - } - entry.push_back(Pair("Whitelisted Project Count", ToString(WHITELISTED_PROJECTS))); - entry.push_back(Pair("Grand-Total Verified RAC",mytotalrac)); - entry.push_back(Pair("Grand-Total Network RAC",nettotalrac)); - entry.push_back(Pair("Total Magnitude for All Projects",TotalMagnitude)); - entry.push_back(Pair("Grand-Total Whitelisted Projects",ToString(WHITELISTED_PROJECTS))); - entry.push_back(Pair("Participating Project Count",ParticipatingProjectCount)); - Mag = TotalMagnitude; - std::string babyNarr = "(" + RoundToString(TotalUserVerifiedRAC,2) + "/" + RoundToString(TotalProjectRAC,2) + ")/" + ToString(WHITELISTED_PROJECTS) + "*" + ToString(NeuralNetworkMultiplier) + "="; - entry.push_back(Pair(babyNarr,Mag)); - results.push_back(entry); - return results; + entry.push_back(Pair("ERROR", "No Neural Reponse; Try again later.")); } + results.push_back(entry); } else if (sitem == "superblocks") { @@ -4218,21 +4149,23 @@ Value listitem(const Array& params, bool fHelp) } else if (sitem == "projects") { - for(map::iterator ii=mvBoincProjects.begin(); ii!=mvBoincProjects.end(); ++ii) + for (const auto item : AppCacheFilter("project")) { + Object entry; - StructCPID structcpid = mvBoincProjects[(*ii).first]; + std::string sProjectKey = item.first; + std::vector vProjectKey = split(sProjectKey, ";"); + std::string sProjectName = ToOfficialName(vProjectKey[1]); + std::string sProjectURL = item.second; + sProjectURL.erase(std::remove(sProjectURL.begin(), sProjectURL.end(), '@'), sProjectURL.end()); - if (structcpid.initialized) - { - Object entry; - entry.push_back(Pair("Project",structcpid.projectname)); - entry.push_back(Pair("URL",structcpid.link)); - results.push_back(entry); + if (sProjectName.empty()) + continue; - } + entry.push_back(Pair("Project", sProjectName)); + entry.push_back(Pair("URL", sProjectURL)); + results.push_back(entry); } - return results; } else if (sitem == "leder") { From c79215e09c84f13947de35ad63a08804b791d161 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 19:36:56 -0700 Subject: [PATCH 062/166] changes to list explainmagnitude --- src/main.cpp | 8 ++++---- src/rpcblockchain.cpp | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e1f3628404..72d23a4b4e 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1397,8 +1397,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool* pfMissingInput return error("AcceptToMemoryPool : CheckTransaction failed"); // Verify beacon contract in tx if found - if (!VerifyBeaconContractTx(tx.hashBoinc)) - return tx.DoS(25, error("AcceptToMemoryPool : bad beacon contract in tx; rejected")); + //if (!VerifyBeaconContractTx(tx.hashBoinc)) + // return tx.DoS(25, error("AcceptToMemoryPool : bad beacon contract in tx; rejected")); // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) @@ -3975,8 +3975,8 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh return DoS(50, error("CheckBlock[] : block timestamp earlier than transaction timestamp")); // Verify beacon contract if a transaction contains a beacon contract - if (!VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) - return DoS(25, error("CheckBlock[] : bad beacon contract found in tx contained within block; rejected")); + //if (!VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) + // return DoS(25, error("CheckBlock[] : bad beacon contract found in tx contained within block; rejected")); } // Check for duplicate txids. This is caught by ConnectInputs(), diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 3b11966f6d..78d71017ee 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -4015,18 +4015,22 @@ Value listitem(const Array& params, bool fHelp) { Object entry; + if (msNeuralResponse.length() > 25) { + entry.push_back(Pair("Neural Response", "true")); + std::vector vMag = split(msNeuralResponse.c_str(),""); + for (unsigned int i = 0; i < vMag.size(); i++) - { entry.push_back(Pair(RoundToString(i+1,0),vMag[i].c_str())); - } } else { - entry.push_back(Pair("ERROR", "No Neural Reponse; Try again later.")); + entry.push_back(Pair("Neural Response", "false; Try again at a later time")); + + AsyncNeuralRequest("explainmag", GlobalCPUMiningCPID.cpid, 10); } results.push_back(entry); @@ -4162,6 +4166,13 @@ Value listitem(const Array& params, bool fHelp) if (sProjectName.empty()) continue; + // If contains an additional stats URL for project stats; remove it for the user to goto the correct website. + if (sProjectURL.find("stats/") != string::npos) + { + std::size_t tFound = sProjectURL.find("stats/"); + sProjectURL.erase(tFound, sProjectURL.length()); + } + entry.push_back(Pair("Project", sProjectName)); entry.push_back(Pair("URL", sProjectURL)); results.push_back(entry); From 1400a90b28115b64ee7776a60abea9b3aa112946 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 19:39:09 -0700 Subject: [PATCH 063/166] reenable brods TrxID --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 72d23a4b4e..60bc325d34 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -8296,7 +8296,7 @@ bool MemorizeMessage(const CTransaction &tx, double dAmount, std::string sRecipi fMessageLoaded = true; } - //WriteCache(sMessageType,sMessageKey+";TrxID",tx.GetHash().GetHex(),nTime); + WriteCache(sMessageType,sMessageKey+";TrxID",tx.GetHash().GetHex(),nTime); } From 11a1e64b6a22271731cbfb3e1c914daae0504f09 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 19:43:59 -0700 Subject: [PATCH 064/166] Remove rest of unused std::string AppCache function which conflicted with AppCache.cpp/h --- src/main.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 60bc325d34..535f6f5c51 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -552,24 +552,6 @@ void GetGlobalStatus() } } - - -//std::string AppCache(std::string key) -//{ -// -// StructCPIDCache setting = mvAppCache["cache"+key]; -// if (!setting.initialized) -// { -// setting.initialized=true; -// setting.xml = ""; -// mvAppCache.insert(map::value_type("cache"+key,setting)); -// mvAppCache["cache"+key]=setting; -// } -// return setting.xml; -//} - - - bool Timer_Main(std::string timer_name, int max_ms) { mvTimers[timer_name] = mvTimers[timer_name] + 1; From 35db222505b575224c0fd0002acd118693c1f135 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 19:47:48 -0700 Subject: [PATCH 065/166] global_objects_noui.hpp change --- src/global_objects_noui.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/global_objects_noui.hpp b/src/global_objects_noui.hpp index 62d651f015..724c99b8c4 100755 --- a/src/global_objects_noui.hpp +++ b/src/global_objects_noui.hpp @@ -149,8 +149,6 @@ extern std::map mvAppCache; //Contains cached bloc //Global CPU Mining CPID: extern MiningCPID GlobalCPUMiningCPID; -//Boinc Valid Projects -extern std::map mvBoincProjects; // Contains all of the allowed boinc projects; // Timers extern std::map mvTimers; // Contains event timers that reset after max ms duration iterator is exceeded From 0ef4ac4883ffbd7354b5ed3af3b6768a3b3dc774 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 20:34:43 -0700 Subject: [PATCH 066/166] renabled the VerifyBeaconContractTx i temp disabled as well as new pr fix was not yet in dev. --- src/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 535f6f5c51..0b605c4616 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1379,8 +1379,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool* pfMissingInput return error("AcceptToMemoryPool : CheckTransaction failed"); // Verify beacon contract in tx if found - //if (!VerifyBeaconContractTx(tx.hashBoinc)) - // return tx.DoS(25, error("AcceptToMemoryPool : bad beacon contract in tx; rejected")); + if (!VerifyBeaconContractTx(tx.hashBoinc)) + return tx.DoS(25, error("AcceptToMemoryPool : bad beacon contract in tx; rejected")); // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) @@ -3957,8 +3957,8 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh return DoS(50, error("CheckBlock[] : block timestamp earlier than transaction timestamp")); // Verify beacon contract if a transaction contains a beacon contract - //if (!VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) - // return DoS(25, error("CheckBlock[] : bad beacon contract found in tx contained within block; rejected")); + if (!VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) + return DoS(25, error("CheckBlock[] : bad beacon contract found in tx contained within block; rejected")); } // Check for duplicate txids. This is caught by ConnectInputs(), From 596d10a37789b57e863b078b038ba9cbbbd0327b Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 22 Oct 2017 07:20:20 +0200 Subject: [PATCH 067/166] Remove "leder" RPC command. --- src/rpcblockchain.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index ab43d70bde..d03b2f4638 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -4232,19 +4232,6 @@ Value listitem(const Array& params, bool fHelp) } return results; } - else if (sitem == "leder") - { - double subsidy = LederstrumpfMagnitude2(450, GetAdjustedTime()); - Object entry; - entry.push_back(Pair("Mag Out For 450",subsidy)); - if (args.length() > 1) - { - double myrac=RoundFromString(args,0); - subsidy = LederstrumpfMagnitude2(myrac, GetAdjustedTime()); - entry.push_back(Pair("Mag Out",subsidy)); - } - results.push_back(entry); - } else if (sitem == "network") { for(map::iterator ii=mvNetwork.begin(); ii!=mvNetwork.end(); ++ii) From e4c917ebfe0fc1ff32434fae77d150f57fcdc793 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 22 Oct 2017 07:35:50 +0200 Subject: [PATCH 068/166] Remove "list staking" RPC command. --- src/rpcblockchain.cpp | 6 ---- src/rpcwallet.cpp | 64 ------------------------------------------- 2 files changed, 70 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index e49cb678ea..5057650534 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -60,7 +60,6 @@ double GetOutstandingAmountOwed(StructCPID &mag, std::string cpid, int64_t lockt bool ComputeNeuralNetworkSupermajorityHashes(); bool UpdateNeuralNetworkQuorumData(); extern Array LifetimeReport(std::string cpid); -Array StakingReport(); extern std::string AddContract(std::string sType, std::string sName, std::string sContract); StructCPID GetLifetimeCPID(const std::string& cpid, const std::string& sFrom); void WriteCache(std::string section, std::string key, std::string value, int64_t locktime); @@ -4081,11 +4080,6 @@ Value listitem(const Array& params, bool fHelp) results = LifetimeReport(cpid); return results; } - else if (sitem == "staking") - { - results = StakingReport(); - return results; - } else if (sitem == "currenttime") { diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 82c89f6fed..a3ac4cb709 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -23,8 +23,6 @@ extern void ThreadTopUpKeyPool(void* parg); double CoinToDouble(double surrogate); std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); -extern Array StakingReport(); - extern void ThreadCleanWalletPassphrase(void* parg); extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry); @@ -1253,68 +1251,6 @@ static void MaybePushAddress(Object & entry, const CTxDestination &dest) } } - - -Array StakingReport() -{ - - Array results; - Object c; - std::string Narr = ToString(GetAdjustedTime()); - c.push_back(Pair("Staking Report",Narr)); - results.push_back(c); - Object entry; - int64_t nCoinStakeTotal = 0; - int64_t nNonCoinStakeTotal = 0; - int64_t nStake = 0; - int64_t nImmature = 0; - int64_t nDepthImmature = 0; - LOCK2(cs_main, pwalletMain->cs_wallet); - for (map::const_iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx* pcoin = &(*it).second; - int64_t amt = pwalletMain->GetCredit(*pcoin); - - if (pcoin->IsCoinStake()) - { - nCoinStakeTotal += amt; - if (pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) - { - nStake += amt; - } - else - { - - if (pcoin->GetBlocksToMaturity() < 1) - { - nImmature+=amt; - } - else - { - if (pcoin->GetDepthInMainChain() < 1) nDepthImmature += amt; - } - } - - } - else - { - //Sent Tx - nNonCoinStakeTotal += amt; - - } - } - - entry.push_back(Pair("CoinStakeTotal", CoinToDouble(nCoinStakeTotal))); - entry.push_back(Pair("Non-CoinStakeTotal", CoinToDouble(nNonCoinStakeTotal))); - entry.push_back(Pair("Blocks Immature", CoinToDouble(nImmature))); - entry.push_back(Pair("Depth Immature", CoinToDouble(nDepthImmature))); - entry.push_back(Pair("Total Immature", CoinToDouble(nImmature+nDepthImmature))); - entry.push_back(Pair("Total Eligibile for Staking", CoinToDouble(nStake))); - results.push_back(entry); - return results; - -} - void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter=MINE_SPENDABLE) { int64_t nFee; From 69d67e955b014dbf7cbfd0631232c79d7ab02982 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 22 Oct 2017 07:38:00 +0200 Subject: [PATCH 069/166] Remove "list newbieage" RPC command. --- src/rpcblockchain.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 5057650534..446a03bd7a 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -4133,16 +4133,6 @@ Value listitem(const Array& params, bool fHelp) results = MagnitudeReport(msPrimaryCPID); return results; } - else if (sitem=="newbieage") - { - double dBeaconDt = BeaconTimeStamp(args,false); - Object entry; - entry.push_back(Pair("Sent",dBeaconDt)); - dBeaconDt = BeaconTimeStamp(args,true); - entry.push_back(Pair("Sent With ZeroOut Feature",dBeaconDt)); - results.push_back(entry); - return results; - } else if (sitem == "projects") { for (const auto item : AppCacheFilter("project")) From efafa3d61431766d9133240a941bbc0d94313fc2 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 22 Oct 2017 07:53:43 +0200 Subject: [PATCH 070/166] Remove "getsubsidy" PoW RPC command. --- src/bitcoinrpc.cpp | 1 - src/bitcoinrpc.h | 1 - src/rpcmining.cpp | 10 ---------- 3 files changed, 12 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index dde1e81b56..369e6997f3 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -240,7 +240,6 @@ static const CRPCCommand vRPCCommands[] = { "getnettotals", &getnettotals, true, true }, { "getdifficulty", &getdifficulty, true, false }, { "getinfo", &getinfo, true, false }, - { "getsubsidy", &getsubsidy, true, false }, { "getmininginfo", &getmininginfo, true, false }, { "getstakinginfo", &getmininginfo, true, false }, { "getnewaddress", &getnewaddress, true, false }, diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 2421b84264..532e8b8c94 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -151,7 +151,6 @@ extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool f extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value sendalert(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getsubsidy(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnettotals(const json_spirit::Array& params, bool fHelp); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index d6ec303e7b..610d55860a 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -26,16 +26,6 @@ std::string GetNeuralNetworkSupermajorityHash(double& out_popularity); int64_t GetRSAWeightByCPID(std::string cpid); -Value getsubsidy(const Array& params, bool fHelp) -{ - if (fHelp || params.size() > 1) - throw runtime_error( - "getsubsidy [nTarget]\n" - "Returns proof-of-work subsidy value for the specified value of target."); - - return (uint64_t)GetProofOfWorkReward(0, GetAdjustedTime(),0); -} - Value getmininginfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) From 9cab2f0c5f4116f043190c4596bd5654d7691040 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sat, 21 Oct 2017 23:11:09 -0700 Subject: [PATCH 071/166] Transaction Description Overhaul (#696) Transaction Description Overhaul Cleaned up transactiondesc to make it more readable then it was originally. --- src/qt/transactiondesc.cpp | 194 ++++++++++--------- src/rpcrawtransaction.cpp | 384 +++++++++++++++++++++++++++++++------ 2 files changed, 431 insertions(+), 147 deletions(-) diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 91c25e5117..239c43c041 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -18,15 +18,15 @@ #include "json/json_spirit_writer_template.h" #include "json/json_spirit_utils.h" -void GetTxStakeBoincHashInfo(json_spirit::mObject& res, const CMerkleTx& mtx); -void GetTxNormalBoincHashInfo(json_spirit::mObject& res, const CMerkleTx& mtx); +std::vector> GetTxStakeBoincHashInfo(const CMerkleTx& mtx); +std::vector> GetTxNormalBoincHashInfo(const CMerkleTx& mtx); QString ToQString(std::string s) { - QString str1 = QString::fromUtf8(s.c_str()); - return str1; -} + QString str1 = QString::fromUtf8(s.c_str()); + return str1; +} QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) { @@ -36,26 +36,29 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) { if (wtx.nLockTime < LOCKTIME_THRESHOLD) return tr("Open for %n more block(s)", "", wtx.nLockTime - nBestHeight); + else return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.nLockTime)); } + else { int nDepth = wtx.GetDepthInMainChain(); + if (nDepth < 0) return tr("conflicted"); + else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) return tr("%1/offline").arg(nDepth); + else if (nDepth < 10) return tr("%1/unconfirmed").arg(nDepth); + else return tr("%1 confirmations").arg(nDepth); } } - - - std::string PubKeyToGRCAddress(const CScript& scriptPubKey) { txnouttype type; @@ -67,25 +70,20 @@ std::string PubKeyToGRCAddress(const CScript& scriptPubKey) return ""; } - std::string grcaddress = ""; - for (auto const& addr : addresses) - { - grcaddress = CBitcoinAddress(addr).ToString(); - } - return grcaddress; -} - - + std::string grcaddress = ""; + for (auto const& addr : addresses) + grcaddress = CBitcoinAddress(addr).ToString(); + return grcaddress; +} QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) { - - QString strHTML; LOCK2(cs_main, wallet->cs_wallet); + strHTML.reserve(9250); strHTML += ""; @@ -93,36 +91,33 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) int64_t nCredit = wtx.GetCredit(); int64_t nDebit = wtx.GetDebit(); int64_t nNet = nCredit - nDebit; + int nRequests = wtx.GetRequestCount(); strHTML += "" + tr("Status") + ": " + FormatTxStatus(wtx); - int nRequests = wtx.GetRequestCount(); + if (nRequests != -1) { if (nRequests == 0) strHTML += tr(", has not been successfully broadcast yet"); + else if (nRequests > 0) strHTML += tr(", broadcast through %n node(s)", "", nRequests); } - strHTML += "
"; + strHTML += "
"; strHTML += "" + tr("Date") + ": " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "
"; - // // From - // if (wtx.IsCoinBase()) - { strHTML += "" + tr("Source") + ": " + tr("Generated in CoinBase") + "
"; - } + else if (wtx.IsCoinStake()) - { strHTML += "" + tr("Source") + ": " + tr("Generated, PoS") + "
"; - } + + // Online transaction else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty()) - { - // Online transaction strHTML += "" + tr("From") + ": " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "
"; - } + else { // Offline transaction @@ -134,6 +129,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) if (wallet->IsMine(txout)) { CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) { if (wallet->mapAddressBook.count(address)) @@ -141,73 +137,80 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) strHTML += "" + tr("From") + ": " + tr("unknown") + "
"; strHTML += "" + tr("To") + ": "; strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); + if (!wallet->mapAddressBook[address].empty()) strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")"; + else strHTML += " (" + tr("own address") + ")"; + strHTML += "
"; } } + break; } } } } - // // To - // if (wtx.mapValue.count("to") && !wtx.mapValue["to"].empty()) { // Online transaction std::string strAddress = wtx.mapValue["to"]; + strHTML += "" + tr("To") + ": "; + CTxDestination dest = CBitcoinAddress(strAddress).Get(); + if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].empty()) strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest]) + " "; + strHTML += GUIUtil::HtmlEscape(strAddress) + "
"; } - // // Amount - // if (wtx.IsCoinBase() && nCredit == 0) { - // // Coinbase - // int64_t nUnmatured = 0; + for (auto const& txout : wtx.vout) nUnmatured += wallet->GetCredit(txout); + strHTML += "" + tr("Credit") + ": "; + if (wtx.IsInMainChain()) strHTML += BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")"; + else strHTML += "(" + tr("not accepted") + ")"; + strHTML += "
"; } + else if (nNet > 0) { - // // Credit - // strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet) + "
"; } + else { bool fAllFromMe = true; + for (auto const& txin : wtx.vin) fAllFromMe = fAllFromMe && wallet->IsMine(txin); bool fAllToMe = true; + for (auto const& txout : wtx.vout) fAllToMe = fAllToMe && wallet->IsMine(txout); if (fAllFromMe) { - // // Debit - // for (auto const& txout : wtx.vout) { if (wallet->IsMine(txout)) @@ -217,11 +220,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) { // Offline transaction CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) { strHTML += "" + tr("To") + ": "; + if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty()) strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " "; + strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); strHTML += "
"; } @@ -235,23 +241,27 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) // Payment to self int64_t nChange = wtx.GetChange(); int64_t nValue = nCredit - nChange; + strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nValue) + "
"; strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nValue) + "
"; } int64_t nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) strHTML += "" + tr("Transaction fee") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nTxFee) + "
"; } + else { - // // Mixed debit transaction - // for (auto const& txin : wtx.vin) + if (wallet->IsMine(txin)) strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "
"; + for (auto const& txout : wtx.vout) + if (wallet->IsMine(txout)) strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "
"; } @@ -259,106 +269,118 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) strHTML += "" + tr("Net amount") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet, true) + "
"; - // // Message - // if (wtx.mapValue.count("message") && !wtx.mapValue["message"].empty()) strHTML += "
" + tr("Message") + ":
" + GUIUtil::HtmlEscape(wtx.mapValue["message"], true) + "
"; + if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty()) strHTML += "
" + tr("Comment") + ":
" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "
"; - strHTML += "" + tr("Transaction ID") + ": " + wtx.GetHash().ToString().c_str() + "
"; + strHTML += "" + tr("TX ID") + ": " + wtx.GetHash().ToString().c_str() + "
"; + + std::string sHashBlock = wtx.hashBlock.ToString(); + + if (wtx.hashBlock == 0) + strHTML += "" + tr("Block Hash") + ": Not yet in chain
"; + + else + strHTML += "" + tr("Block Hash") + ": " + sHashBlock.c_str() + "
"; if (wtx.IsCoinBase() || wtx.IsCoinStake()) { + strHTML += "



" + tr("Transaction Stake Data") + "

"; + + std::vector> vTxStakeInfoIn = GetTxStakeBoincHashInfo(wtx); + + for (auto const& vTxStakeInfo : vTxStakeInfoIn) + { + strHTML += ""; + strHTML += MakeSafeMessage(vTxStakeInfo.first).c_str(); + strHTML += ": "; + strHTML += MakeSafeMessage(vTxStakeInfo.second).c_str(); + strHTML += "
"; + } - json_spirit::mObject out; - GetTxStakeBoincHashInfo(out, wtx); - strHTML += "
" + GUIUtil::HtmlEscape(json_spirit::write_string(json_spirit::mValue(out),true), true) + - "

" + tr("Gridcoin generated coins must mature 110 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
"; + strHTML == "

" + tr("Gridcoin generated coins must mature 110 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
"; } - else + + else if (!wtx.hashBoinc.empty()) { + strHTML += "

" + tr("Transaction Message Data") + "

"; - json_spirit::mObject out; - GetTxNormalBoincHashInfo(out, wtx); - strHTML += "
" + GUIUtil::HtmlEscape(json_spirit::write_string(json_spirit::mValue(out),true), true) + - "
"; + std::vector> vTxNormalInfoIn = GetTxNormalBoincHashInfo(wtx); + + for (auto const& vTxNormalInfo : vTxNormalInfoIn) + { + strHTML += ""; + strHTML += MakeSafeMessage(vTxNormalInfo.first).c_str(); + strHTML += ": "; + strHTML += MakeSafeMessage(vTxNormalInfo.second).c_str(); + strHTML += "
"; + } } - // // Debug view 12-7-2014 - Halford - // - // Smart Contracts msHashBoinc = ""; - if (fDebug || true) { - strHTML += "

" + tr("Information") + "

"; + strHTML += "

" + tr("Transaction Debits/Credits") + "

"; + for (auto const& txin : wtx.vin) + if(wallet->IsMine(txin)) strHTML += "" + tr("Debit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "
"; + for (auto const& txout : wtx.vout) + if(wallet->IsMine(txout)) strHTML += "" + tr("Credit") + ": " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "
"; - strHTML += "
" + tr("Transaction") + ":
"; + strHTML += "
" + tr("Transaction Data") + "

"; strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true); CTxDB txdb("r"); // To fetch source txouts - //Decrypt any embedded messages - std::string eGRCMessage = ExtractXML(wtx.hashBoinc,"",""); - std::string sGRCMessage = MakeSafeMessage(eGRCMessage); - std::string sOptionsNarr = ExtractXML(wtx.hashBoinc,"",""); + // Contracts //std::string sContractLength = RoundToString((double)wtx.hashBoinc.length(),0); //std::string sContractInfo = ""; //if (wtx.hashBoinc.length() > 255) sContractInfo = ": " + wtx.hashBoinc.substr(0,255); - strHTML += "
Notes:
 " 
-            + QString::fromStdString(sGRCMessage) + "


"; - if (sOptionsNarr.length() > 1) - { - std::string oOptionsNarr = MakeSafeMessage(sOptionsNarr); - strHTML += "
Options:

 " + QString::fromStdString(oOptionsNarr) + "


"; - - } - if (fDebug3) - { + + //if (fDebug3) + //{ //Extract contract here from : wtx.hashBoinc - contract key //strHTML += "
Contracts: " + QString::fromStdString(sContractLength) + "


"; - } + //} + msHashBoinc += wtx.hashBoinc; - strHTML += "
" + tr("Inputs") + ":"; + strHTML += "
" + tr("Transaction Inputs") + ""; strHTML += "

    "; - for (auto const& txin : wtx.vin) { COutPoint prevout = txin.prevout; CTransaction prev; + if(txdb.ReadDiskTx(prevout.hash, prev)) { if (prevout.n < prev.vout.size()) { strHTML += "
  • "; - //Inputs: 7-31-2015 + + //Inputs: 7-31-2015 const CTxOut &vout = prev.vout[prevout.n]; - std::string grcFrom = PubKeyToGRCAddress(vout.scriptPubKey); - strHTML=strHTML + " " + QString::fromStdString(grcFrom) + " "; CTxDestination address; + if (ExtractDestination(vout.scriptPubKey, address)) - { - if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty()) - strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + " "; strHTML += QString::fromStdString(CBitcoinAddress(address).ToString()); - } - strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, vout.nValue); - strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? tr("true") : tr("false")) + "
  • "; + + strHTML += " " + tr("Amount") + "=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, vout.nValue); + strHTML += " IsMine=" + (wallet->IsMine(vout) ? tr("true") : tr("false")) + ""; } } } diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index a479d4d0bc..a451bf79b8 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -12,9 +12,8 @@ #include "main.h" #include "net.h" #include "wallet.h" -//#include "univalue.h" #include "upgrader.h" - +#include "ui_interface.h" using namespace std; using namespace boost; using namespace boost::assign; @@ -24,110 +23,373 @@ extern std::string GetTxProject(uint256 hash, int& out_blocknumber, int& out_blo extern void Imker(void *kippel); extern Upgrader upgrader; +extern std::vector> GetTxStakeBoincHashInfo(const CMerkleTx& mtx); +extern std::vector> GetTxNormalBoincHashInfo(const CMerkleTx& mtx); +std::string TimestampToHRDate(double dtm); +std::string GetPollXMLElementByPollTitle(std::string pollname, std::string XMLElement1, std::string XMLElement2); +std::string GetShareType(double dShareType); +bool PollCreatedAfterSecurityUpgrade(std::string pollname); +double DoubleFromAmount(int64_t amount); + #ifdef QT_GUI #include "qt/upgradedialog.h" extern Checker checker; #endif -void GetTxStakeBoincHashInfo(json_spirit::mObject& res, const CMerkleTx& mtx) +std::vector> GetTxStakeBoincHashInfo(const CMerkleTx& mtx) { assert(mtx.IsCoinStake() || mtx.IsCoinBase()); - - res["blockhash"]=mtx.hashBlock.GetHex(); + std::vector> res; // Fetch BlockIndex for tx block CBlockIndex* pindex = NULL; CBlock block; { map::iterator mi = mapBlockIndex.find(mtx.hashBlock); + if (mi == mapBlockIndex.end()) { - res["error"] = "block_not_in_index"; - return; + res.push_back(std::make_pair(_("ERROR"), _("Block not in index"))); + + return res; } + pindex = (*mi).second; + if (!block.ReadFromDisk(pindex)) { - res["error"] = "block_read_failed"; - return; + res.push_back(std::make_pair(_("ERROR"), _("Block read failed"))); + + return res; } } //Deserialize MiningCPID bb = DeserializeBoincBlock(block.vtx[0].hashBoinc,block.nVersion); - res["height"]=pindex->nHeight; - res["version"]=block.nVersion; + res.push_back(std::make_pair(_("Height"), ToString(pindex->nHeight))); + res.push_back(std::make_pair(_("Block Version"), ToString(block.nVersion))); + res.push_back(std::make_pair(_("Difficulty"), RoundToString(GetBlockDifficulty(block.nBits),8))); + res.push_back(std::make_pair(_("CPID"), bb.cpid)); + res.push_back(std::make_pair(_("Interest"), RoundToString(bb.InterestSubsidy,8))); - res["cpid"]=bb.cpid; - res["Magnitude"]=bb.Magnitude; - res["Interest"]=bb.InterestSubsidy; - res["BoincReward"]=bb.ResearchSubsidy; - res["Difficulty"]=GetBlockDifficulty(block.nBits); - - - if(fDebug) + if (bb.ResearchAverageMagnitude > 0) { - res["xbbBoincPublicKey"]=bb.BoincPublicKey; + res.push_back(std::make_pair(_("Boinc Reward"), RoundToString(bb.ResearchSubsidy,8))); + res.push_back(std::make_pair(_("Magnitude"), RoundToString(bb.Magnitude,8))); + res.push_back(std::make_pair(_("Average Magnitude"), RoundToString(bb.ResearchAverageMagnitude, 8))); + res.push_back(std::make_pair(_("Research Age"), RoundToString(bb.ResearchAge, 8))); + } - res["xbbOrganization"]=bb.Organization; - res["xbbClientVersion"]=bb.clientversion; + res.push_back(std::make_pair(_("Is Superblock"), (bb.superblock.length() >= 20 ? "Yes" : "No"))); - res["xbbNeuralHash"]=bb.NeuralHash; - res["xbbCurrentNeuralHash"]=bb.CurrentNeuralHash; - res["xbbNeuralContractSize"]=bb.superblock.length(); - } - else + if(fDebug) { - if(bb.superblock.length()>=20) - { - res["IsSuperBlock"]=true; - } + if (bb.superblock.length() >= 20) + res.push_back(std::make_pair(_("Neural Contract Binary Size"), ToString(bb.superblock.length()))); + + res.push_back(std::make_pair(_("Neural Hash"), bb.NeuralHash)); + res.push_back(std::make_pair(_("Current Neural Hash"), bb.CurrentNeuralHash)); + res.push_back(std::make_pair(_("Client Version"), bb.clientversion)); + res.push_back(std::make_pair(_("Organization"), bb.Organization)); + res.push_back(std::make_pair(_("Boinc Public Key"), bb.BoincPublicKey)); } + return res; } -void GetTxNormalBoincHashInfo(json_spirit::mObject& res, const CMerkleTx& mtx) +std::vector> GetTxNormalBoincHashInfo(const CMerkleTx& mtx) { assert(!mtx.IsCoinStake() && !mtx.IsCoinBase()); - res["blockhash"]=mtx.hashBlock.GetHex(); - const std::string &hashBoinc = mtx.hashBoinc; - const std::string &msg = mtx.hashBoinc; - - /* Possible formats: - * transaction - * a message - * cpid beacon - * vote - * poll - * unknown / text - */ + std::vector> res; + + try + { + const std::string &msg = mtx.hashBoinc; - res["bhLength"]=msg.length(); + res.push_back(std::make_pair(_("Network Date"), TimestampToHRDate((double)mtx.nTime))); - std::string sMessageType = ExtractXML(msg,"",""); - std::string sTrxMessage = ExtractXML(msg,"",""); + if (fDebug) + res.push_back(std::make_pair(_("Message Length"), ToString(msg.length()))); - if(sMessageType.length()) - { - res["bhType"]="message"; - res["msgType"]=sMessageType; - } - else if(sTrxMessage.length()) - { - res["bhType"]="TrxWithNote"; + std::string sMessageType = ExtractXML(msg, "", ""); + std::string sTxMessage = ExtractXML(msg, "", ""); + std::string sRainMessage = ExtractXML(msg, "", ""); + + if (sMessageType.length()) + { + if (sMessageType == "beacon") + { + std::string sBeaconAction = ExtractXML(msg, "", ""); + std::string sBeaconCPID = ExtractXML(msg, "", ""); + + if (sBeaconAction == "A") + { + res.push_back(std::make_pair(_("Message Type"), _("Add Beacon Contract"))); + + std::string sBeaconEncodedContract = ExtractXML(msg, "", ""); + + if (sBeaconEncodedContract.length() < 256) + { + // If for whatever reason the contract is not a proper one and the average length does exceed this size; Without this a seg fault will occur on the DecodeBase64 + // Another example is if an admin accidently uses add instead of delete in addkey to remove a beacon the 1 in 1 would cause a seg fault as well + res.push_back(std::make_pair(_("ERROR"), _("Contract length for beacon is less then 256 in length. Size: ") + ToString(sBeaconEncodedContract.length()))); + + if (fDebug) + res.push_back(std::make_pair(_("Message Data"), sBeaconEncodedContract)); + + return res; + } + + std::string sBeaconDecodedContract = DecodeBase64(sBeaconEncodedContract); + std::vector vBeaconContract = split(sBeaconDecodedContract.c_str(), ";"); + std::string sBeaconAddress = vBeaconContract[2]; + std::string sBeaconPublicKey = vBeaconContract[3]; + + res.push_back(std::make_pair(_("CPID"), sBeaconCPID)); + res.push_back(std::make_pair(_("Address"), sBeaconAddress)); + res.push_back(std::make_pair(_("Public Key"), sBeaconPublicKey)); + } + + else if (sBeaconAction == "D") + { + res.push_back(std::make_pair(_("Message Type"), _("Delete Beacon Contract"))); + res.push_back(std::make_pair(_("CPID"), sBeaconCPID)); + } + } + + else if (sMessageType == "poll") + { + std::string sPollType = ExtractXML(msg, "", ""); + std::string sPollTitle = ExtractXML(msg, "", ""); + std::replace(sPollTitle.begin(), sPollTitle.end(), '_', ' '); + std::string sPollDays = ExtractXML(msg, "", ""); + std::string sPollQuestion = ExtractXML(msg, "", ""); + std::string sPollAnswers = ExtractXML(msg, "", ""); + std::string sPollShareType = ExtractXML(msg, "", ""); + std::string sPollUrl = ExtractXML(msg, "", "", ""); + std::replace(sPollAnswers.begin(), sPollAnswers.end(), ';', ','); + sPollShareType = GetShareType(std::stod(sPollShareType)); + + if (Contains(sPollType, "[Foundation")) + res.push_back(std::make_pair(_("Message Type"), _("Add Foundation Poll"))); + + else + res.push_back(std::make_pair(_("Message Type"), _("Add Poll"))); + + res.push_back(std::make_pair(_("Title"), sPollTitle)); + res.push_back(std::make_pair(_("Question"), sPollQuestion)); + res.push_back(std::make_pair(_("Answers"), sPollAnswers)); + res.push_back(std::make_pair(_("Share Type"), sPollShareType)); + res.push_back(std::make_pair(_("URL"), sPollUrl)); + res.push_back(std::make_pair(_("Duration"), sPollDays + _(" days"))); + res.push_back(std::make_pair(_("Expires"), TimestampToHRDate(std::stod(sPollExpiration)))); + } + + else if (sMessageType == "vote") + { + std::string sVoteTitled = ExtractXML(msg, "", ""); + std::string sVoteShareType = GetPollXMLElementByPollTitle(sVoteTitled, "", ""); + std::string sVoteTitle = sVoteTitled; + std::replace(sVoteTitle.begin(), sVoteTitle.end(), '_', ' '); + std::string sVoteAnswer = ExtractXML(msg, "", ""); + std::replace(sVoteAnswer.begin(), sVoteAnswer.end(), ';', ','); + + res.push_back(std::make_pair(_("Message Type"), _("Vote"))); + res.push_back(std::make_pair(_("Title"), sVoteTitle)); + + if (sVoteShareType.empty()) + { + res.push_back(std::make_pair(_("Share Type"), _("Unable to extract Share Type. Vote likely > 6 months old"))); + res.push_back(std::make_pair(_("Answer"), sVoteAnswer)); + + if (fDebug) + res.push_back(std::make_pair(_("Share Type Debug"), sVoteShareType)); + + return res; + } + + else + res.push_back(std::make_pair(_("Share Type"), GetShareType(std::stod(sVoteShareType)))); + + res.push_back(std::make_pair(_("Answer"), sVoteAnswer)); + + // Basic Variables for all poll types + double dVoteWeight = 0; + double dVoteMagnitude = 0; + double dVoteBalance = 0; + std::string sVoteMagnitude; + std::string sVoteBalance; + + // Get voting magnitude and balance; These fields are always in vote contract + if (!PollCreatedAfterSecurityUpgrade(sVoteTitled)) + { + sVoteMagnitude = ExtractXML(msg, "", ""); + sVoteBalance = ExtractXML(msg, "", ""); + } + + else + { + sVoteMagnitude = ExtractXML(msg, "", ""); + sVoteBalance = ExtractXML(msg, "", ""); + } + + if (sVoteShareType == "1") + dVoteWeight = std::stod(sVoteMagnitude); + + else if (sVoteShareType == "2") + dVoteWeight = std::stod(sVoteBalance); + + else if (sVoteShareType == "3") + { + // For voting mag for mag + balance polls we need to calculate total network magnitude from superblock before vote to use the correct data in formula. + // This gives us an accruate vote shares at that time. We like to keep wallet information as accruate as possible. + // Note during boosted superblocks we get unusual calculations for total network magnitude. + CBlockIndex* pblockindex = mapBlockIndex[mtx.hashBlock]; + CBlock block; + + int nEndHeight = pblockindex->nHeight - (BLOCKS_PER_DAY*14); + + // Incase; Why throw. + if (nEndHeight < 1) + nEndHeight = 1; + + // Iterate back to find previous superblock + while (pblockindex->nHeight > nEndHeight && pblockindex->nIsSuperBlock == 0) + pblockindex = pblockindex->pprev; + + if (pblockindex->nIsSuperBlock == 1) + { + block.ReadFromDisk(pblockindex); + + std::string sHashBoinc = block.vtx[0].hashBoinc; + + MiningCPID vbb = DeserializeBoincBlock(sHashBoinc, block.nVersion); + + std::string sUnpackedSuperblock = UnpackBinarySuperblock(vbb.superblock); + std::string sMagnitudeContract = ExtractXML(sUnpackedSuperblock, "", ""); + + // Since Superblockavg function gives avg for mags yes but total cpids we cannot use this function + // We need the rows_above_zero for Total Network Magnitude calculation with Money Supply Factor. + std::vector vMagnitudeContract = split(sMagnitudeContract, ";"); + int nRowsWithMag = 0; + double dTotalMag = 0; + + for (auto const& sMag : vMagnitudeContract) + { + const std::vector& vFields = split(sMag, ","); + + if (vFields.size() < 2) + continue; + + const std::string& sCPID = vFields[0]; + double dMAG = std::stoi(vFields[1].c_str()); + + if (sCPID.length() > 10) + { + nRowsWithMag++; + dTotalMag += dMAG; + } + } + + double dOutAverage = dTotalMag / ((double)nRowsWithMag + .01); + double dTotalNetworkMagnitude = (double)nRowsWithMag * dOutAverage; + double dMoneySupply = DoubleFromAmount(pblockindex->nMoneySupply); + double dMoneySupplyFactor = (dMoneySupply/dTotalNetworkMagnitude + .01); + + dVoteMagnitude = cdbl(sVoteMagnitude,2); + dVoteBalance = cdbl(sVoteBalance,2); + + if (dVoteMagnitude > 0) + dVoteWeight = ((dMoneySupplyFactor/5.67) * dVoteMagnitude) + std::stod(sVoteBalance); + + else + dVoteWeight = std::stod(sVoteBalance); + + res.push_back(std::make_pair(_("Magnitude"), RoundToString(dVoteMagnitude, 2))); + res.push_back(std::make_pair(_("Balance"), RoundToString(dVoteBalance, 2))); + } + + else + { + res.push_back(std::make_pair(_("ERROR"), _("Unable to obtain superblock data before vote was made to calculate voting weight"))); + + return res; + } + } + + else if (sVoteShareType == "4" || sVoteShareType == "5") + dVoteWeight = 1; + + res.push_back(std::make_pair(_("Weight"), RoundToString(dVoteWeight, 0))); + } + + else if (sMessageType == "project") + { + std::string sProjectName = ExtractXML(msg, "", ""); + std::string sProjectURL = ExtractXML(msg, "", ""); + std::string sProjectAction = ExtractXML(msg, "", ""); + + if (sProjectAction == "A") + res.push_back(std::make_pair(_("Messate Type"), _("Add Project"))); + + else if (sProjectAction == "D") + res.push_back(std::make_pair(_("Message Type"), _("Delete Project"))); + + res.push_back(std::make_pair(_("Name"), sProjectName)); + + if (sProjectAction == "A") + res.push_back(std::make_pair(_("URL"), sProjectURL)); + } + + else + { + res.push_back(std::make_pair(_("Message Type"), _("Unknown"))); + + if (fDebug) + res.push_back(std::make_pair(_("Data"), msg)); + + return res; + } + } + + else if (sTxMessage.length()) + { + res.push_back(std::make_pair(_("Message Type"), _("Text Message"))); + res.push_back(std::make_pair(_("Message"), sTxMessage)); + } + + else if (sRainMessage.length()) + { + res.push_back(std::make_pair(_("Message Type"), _("Text Rain Message"))); + res.push_back(std::make_pair(_("Message"), sRainMessage)); + } + + else if (sMessageType.empty() && sTxMessage.empty() && sRainMessage.empty()) + res.push_back(std::make_pair(_("Message Type"), _("No Attached Messages"))); + + return res; } - else if(msg.length()) + + catch (const std::invalid_argument& e) { - res["bhType"]="Unknown"; + std::string sE(e.what()); + + res.push_back(std::make_pair(_("ERROR"), _("Invalid argument exception while parsing Transaction Message -> ") + sE)); + + return res; } - else + + catch (const std::out_of_range& e) { - res["bhType"]="None"; - } + std::string sE(e.what()); -} + res.push_back(std::make_pair(_("ERROR"), _("Out of rance exception while parsing Transaction Message -> ") + sE)); + return res; + } +} Value downloadblocks(const Array& params, bool fHelp) { From 74ea3423d332f70949c0daff733b18be46a29bfd Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 22 Oct 2017 13:32:46 +0200 Subject: [PATCH 072/166] Fix build error. --- src/rpcrawtransaction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index a451bf79b8..fd3e089895 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -298,8 +298,8 @@ std::vector> GetTxNormalBoincHashInfo(const double dMoneySupply = DoubleFromAmount(pblockindex->nMoneySupply); double dMoneySupplyFactor = (dMoneySupply/dTotalNetworkMagnitude + .01); - dVoteMagnitude = cdbl(sVoteMagnitude,2); - dVoteBalance = cdbl(sVoteBalance,2); + dVoteMagnitude = RoundFromString(sVoteMagnitude,2); + dVoteBalance = RoundFromString(sVoteBalance,2); if (dVoteMagnitude > 0) dVoteWeight = ((dMoneySupplyFactor/5.67) * dVoteMagnitude) + std::stod(sVoteBalance); From 04860635087d01a227ff62cc71185f9856bce440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 22 Oct 2017 09:53:34 +0200 Subject: [PATCH 073/166] Move mandatory condition for Beaconchecks to Checkblock. Also enables the check for all incoming loose transactions even before mandatory, but skips the check for transaction included in pre-mandatory blocks. This way it is more reliable in case of reorgs. --- src/beacon.cpp | 9 +-------- src/main.cpp | 3 ++- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/beacon.cpp b/src/beacon.cpp index 4b42c09de3..a36c84aed2 100755 --- a/src/beacon.cpp +++ b/src/beacon.cpp @@ -138,14 +138,7 @@ std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxS bool VerifyBeaconContractTx(const std::string& txhashBoinc) { - // Mandatory block needed. - // Current bad contracts in chain would cause a fork on sync - // Previous beacons in the past have 3 elements not 4 thus causing empty contract elements as coded in GetBeaconElements - if ( - (fTestNet && nBestHeight <= 378000) - || (!fTestNet && nBestHeight <= 1070000) - ) - return true; // allow sync from 0 till these blocks when this check comes into effect + // Mandatory condition handled in CheckBlock // Check if tx contains beacon advertisement and evaluate for certain conditions std::string chkMessageType = ExtractXML(txhashBoinc, "", ""); diff --git a/src/main.cpp b/src/main.cpp index c2398632e5..c2763c5569 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3956,7 +3956,8 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh return DoS(50, error("CheckBlock[] : block timestamp earlier than transaction timestamp")); // Verify beacon contract if a transaction contains a beacon contract - if (!VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) + // Current bad contracts in chain would cause a fork on sync, skip them + if (nVersion>=9 && !VerifyBeaconContractTx(tx.hashBoinc) && !fLoadingIndex) return DoS(25, error("CheckBlock[] : bad beacon contract found in tx %s contained within block; rejected", tx.GetHash().ToString().c_str())); } From 9e34ea5dc14a34bd8c2cdeb2ff8bce90d75368ec Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sun, 22 Oct 2017 14:24:03 -0700 Subject: [PATCH 074/166] const auto& as requested for mvBoincProjects --- src/rpcblockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 446a03bd7a..2ede196a89 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -4135,7 +4135,7 @@ Value listitem(const Array& params, bool fHelp) } else if (sitem == "projects") { - for (const auto item : AppCacheFilter("project")) + for (const auto& item : AppCacheFilter("project")) { Object entry; From 01c24c801281d6a315341c7be8607680652b9034 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sun, 22 Oct 2017 15:30:53 -0700 Subject: [PATCH 075/166] remove explainmagnitude2 and add force option to explainmagnitude as these functions currently do the same now --- src/rpcblockchain.cpp | 64 ++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 2ede196a89..744bb2db94 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -2045,35 +2045,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("Requested a quorum - waiting for resolution.",1)); results.push_back(entry); } - else if (sItem == "explainmagnitude2") - { - bool force = false; - if (params.size() == 2) - { - std::string optional = params[1].get_str(); - boost::to_lower(optional); - if (optional == "force") force = true; - } - - if (force) msNeuralResponse = ""; - if (msNeuralResponse=="") - { - AsyncNeuralRequest("explainmag",GlobalCPUMiningCPID.cpid,10); - entry.push_back(Pair("Requested Explain Magnitude For",GlobalCPUMiningCPID.cpid)); - } - - std::vector vMag = split(msNeuralResponse.c_str(),""); - for (unsigned int i = 0; i < vMag.size(); i++) - { - entry.push_back(Pair(RoundToString(i+1,0),vMag[i].c_str())); - } - if (msNeuralResponse=="") - { - entry.push_back(Pair("Response","No response.")); - } - - results.push_back(entry); - } else if (sItem == "tally") { bNetAveragesLoaded = false; @@ -2507,7 +2478,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("execute dportally", "Tally magnitudes in superblock")); entry.push_back(Pair("execute encrypt ", "Encrypt a wallet pass phrase (autounlock feature)")); entry.push_back(Pair("execute encryptphrase ", "Encrypt a phrase or message")); - entry.push_back(Pair("execute explainmagnitude2 ", "Explains your neural network magnitude. True is optional for force")); entry.push_back(Pair("execute listallpolldetails", "Displays all polls past and present with details")); entry.push_back(Pair("execute listallpolls", "Displays all polls past and present")); entry.push_back(Pair("execute listpolldetails", "Displays all active polls details")); @@ -4009,10 +3979,34 @@ Value listitem(const Array& params, bool fHelp) results.push_back(entry); } else if (sitem == "explainmagnitude") - { - + { Object entry; + bool bForce = false; + + if (params.size() == 2) + { + std::string sOptional = params[1].get_str(); + + boost::to_lower(sOptional); + + if (sOptional == "force") + bForce = true; + } + + if (bForce) + { + if (msNeuralResponse.length() < 25) + { + entry.push_back(Pair("Neural Response", "Empty; Requesting a response..")); + entry.push_back(Pair("WARNING", "Only force once and try again without force if response is not received. Doing too many force attempts gets a temporary ban from neural node responses")); + + msNeuralResponse = ""; + + AsyncNeuralRequest("explainmag", GlobalCPUMiningCPID.cpid, 10); + } + } + if (msNeuralResponse.length() > 25) { entry.push_back(Pair("Neural Response", "true")); @@ -4024,12 +4018,8 @@ Value listitem(const Array& params, bool fHelp) } else - { entry.push_back(Pair("Neural Response", "false; Try again at a later time")); - AsyncNeuralRequest("explainmag", GlobalCPUMiningCPID.cpid, 10); - } - results.push_back(entry); } else if (sitem == "superblocks") @@ -4279,7 +4269,7 @@ Value listitem(const Array& params, bool fHelp) entry.push_back(Pair("list currenttime", "Displays current unix time as well as UTC time and date")); entry.push_back(Pair("list detailmagnitudecsv", "Records more detailed magnitude report into a csv file")); entry.push_back(Pair("list debugexplainmagnitude", "Displays more in detail your explainmagnitude from NN")); - entry.push_back(Pair("list explainmagnitude", "Displays information about your magnitude from NN")); + entry.push_back(Pair("list explainmagnitude ", "Displays information about your magnitude from NN; Optional force")); entry.push_back(Pair("list lifetime", "Displays information on the life time of your cpid")); entry.push_back(Pair("list magnitude ", "Displays information on magnitude. cpid is optional.")); entry.push_back(Pair("list magnitudecsv", "Records magnitude report into a csv file")); From 2e36b68787a9fe72b4f8b68e70f6364d195958d6 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Sun, 22 Oct 2017 15:33:56 -0700 Subject: [PATCH 076/166] change to make force a true entry --- src/rpcblockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 744bb2db94..d73178376d 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -3990,7 +3990,7 @@ Value listitem(const Array& params, bool fHelp) boost::to_lower(sOptional); - if (sOptional == "force") + if (sOptional == "true") bForce = true; } @@ -4269,7 +4269,7 @@ Value listitem(const Array& params, bool fHelp) entry.push_back(Pair("list currenttime", "Displays current unix time as well as UTC time and date")); entry.push_back(Pair("list detailmagnitudecsv", "Records more detailed magnitude report into a csv file")); entry.push_back(Pair("list debugexplainmagnitude", "Displays more in detail your explainmagnitude from NN")); - entry.push_back(Pair("list explainmagnitude ", "Displays information about your magnitude from NN; Optional force")); + entry.push_back(Pair("list explainmagnitude ", "Displays information about your magnitude from NN; Optional true to force response")); entry.push_back(Pair("list lifetime", "Displays information on the life time of your cpid")); entry.push_back(Pair("list magnitude ", "Displays information on magnitude. cpid is optional.")); entry.push_back(Pair("list magnitudecsv", "Records magnitude report into a csv file")); From b9fa6511f99892f9a370ec01c98c31c096c9f25c Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 23 Oct 2017 10:06:39 +0200 Subject: [PATCH 077/166] Remove unused ExtractHTML. --- src/main.cpp | 34 ---------------------------------- src/rpcblockchain.cpp | 1 - 2 files changed, 35 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5ca75c19f0..7c1206066b 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -143,7 +143,6 @@ set setpwalletRegistered; CCriticalSection cs_main; extern std::string NodeAddress(CNode* pfrom); -extern std::string ExtractHTML(std::string HTMLdata, std::string tagstartprefix, std::string tagstart_suffix, std::string tag_end); CTxMemPool mempool; unsigned int nTransactionsUpdated = 0; @@ -4906,39 +4905,6 @@ std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end return extraction; } -std::string ExtractHTML(std::string HTMLdata, std::string tagstartprefix, std::string tagstart_suffix, std::string tag_end) -{ - - std::string extraction = ""; - string::size_type loc = HTMLdata.find( tagstartprefix, 0 ); - if( loc != string::npos ) - { - //Find the end of the start tag - string::size_type loc_EOStartTag = HTMLdata.find( tagstart_suffix, loc+tagstartprefix.length()); - if (loc_EOStartTag != string::npos ) - { - - string::size_type loc_end = HTMLdata.find( tag_end, loc_EOStartTag+tagstart_suffix.length()); - if (loc_end != string::npos ) - { - extraction = HTMLdata.substr(loc_EOStartTag+(tagstart_suffix.length()), loc_end-loc_EOStartTag-(tagstart_suffix.length())); - extraction = strReplace(extraction,",",""); - if (Contains(extraction,"\r\n")) - { - std::vector vExtract = split(extraction,"\r\n"); - if (vExtract.size() >= 2) - { - extraction = vExtract[2]; - return extraction; - } - } - } - } - } - return extraction; -} - - std::string RetrieveMd5(std::string s1) { try diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index d73178376d..069a584384 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -69,7 +69,6 @@ bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); int64_t GetMaximumBoincSubsidy(int64_t nTime); double GRCMagnitudeUnit(int64_t locktime); std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); -std::string ExtractHTML(std::string HTMLdata, std::string tagstartprefix, std::string tagstart_suffix, std::string tag_end); std::string NeuralRequest(std::string MyNeuralRequest); extern bool AdvertiseBeacon(std::string &sOutPrivKey, std::string &sOutPubKey, std::string &sError, std::string &sMessage); From ce8061ede43f9ae697e13ae945ced10ea574dd16 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 23 Oct 2017 10:14:28 +0200 Subject: [PATCH 078/166] Remove unnecessary forward declarations. --- src/main.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7c1206066b..03ef37c8fa 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -168,17 +168,12 @@ std::string DefaultOrgKey(int key_length); double MintLimiter(double PORDiff,int64_t RSA_WEIGHT,std::string cpid,int64_t locktime); double GetLastPaymentTimeByCPID(std::string cpid); -extern bool Contains(const std::string& data, const std::string& instring); - extern double CoinToDouble(double surrogate); extern int64_t PreviousBlockAge(); void CheckForUpgrade(); int64_t GetRSAWeightByCPID(std::string cpid); extern MiningCPID GetMiningCPID(); extern StructCPID GetStructCPID(); - -extern void SetAdvisory(); -extern bool InAdvisory(); json_spirit::Array MagnitudeReportCSV(bool detail); int64_t nLastBlockSolved = 0; //Future timestamp From f5d3835bc89022bfeadd9d3bc00cdcb071eca204 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 23 Oct 2017 10:40:31 +0200 Subject: [PATCH 079/166] Remove automatic block downloading from service function. If the user wants to download the chain it can be done with a manual trigger. The automatic trigger was super restrictive anyway. --- src/main.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 03ef37c8fa..ba721fa850 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,7 +54,6 @@ extern void ResetTimerMain(std::string timer_name); extern bool TallyResearchAverages(bool Forcefully); extern void IncrementCurrentNeuralNetworkSupermajority(std::string NeuralHash, std::string GRCAddress, double distance); bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature); -int DownloadBlocks(); int DetermineCPIDType(std::string cpid); extern MiningCPID GetInitializedMiningCPID(std::string name, std::map& vRef); std::string GetListOfWithConsensus(std::string datatype); @@ -300,7 +299,6 @@ std::string msPrimaryCPID; double mdPORNonce = 0; double mdLastPorNonce = 0; double mdMachineTimerLast = 0; -bool mbBlocksDownloaded = false; // Mining status variables std::string msHashBoinc; std::string msMiningErrors; @@ -4232,22 +4230,7 @@ void GridcoinServices() } #endif // Services thread activity - - //This is Gridcoins Service thread; called once per block - if (nBestHeight > 100 && nBestHeight < 200) - { - if (GetArg("-suppressdownloadblocks", "true") == "false") - { - std::string email = GetArgument("email", "NA"); - if (email.length() > 5 && !mbBlocksDownloaded) - { - #if defined(WIN32) && defined(QT_GUI) - mbBlocksDownloaded=true; - DownloadBlocks(); - #endif - } - } - } + //Dont perform the following functions if out of sync if (pindexBest->nHeight < nGrandfather) return; From 09f45ee4a20f965b2a7214412616388a6a51007a Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 29 Sep 2017 05:24:00 +0200 Subject: [PATCH 080/166] Extract PoR checks from CheckBlock and call it in AcceptBlock instead. --- src/main.cpp | 200 +++++++++++++++++++++++++++++---------------------- src/main.h | 5 ++ 2 files changed, 118 insertions(+), 87 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ba721fa850..c155876b0e 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -2147,6 +2147,63 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) return true; } +bool CheckProofOfResearch( + const CBlockIndex* pindexPrev, //previous block in chain index + const CBlock &block) //block to check +{ + if(block.vtx.size() == 0 || + !block.IsProofOfStake() || + pindexPrev->nHeight <= nGrandfather || + !IsResearchAgeEnabled(pindexPrev->nHeight)) + return true; + + MiningCPID bb = DeserializeBoincBlock(block.vtx[0].hashBoinc, block.nVersion); + if(!IsResearcher(bb.cpid)) + return true; + + //For higher security, plus lets catch these bad blocks before adding them to the chain to prevent reorgs: + double OUT_POR = 0; + double OUT_INTEREST = 0; + double dAccrualAge = 0; + double dMagnitudeUnit = 0; + double dAvgMagnitude = 0; + int64_t nCoinAge = 0; + int64_t nFees = 0; + + // 6-4-2017 - Verify researchers stored block magnitude + double dNeuralNetworkMagnitude = CalculatedMagnitude2(bb.cpid, block.nTime, false); + if (bb.Magnitude > 0 && + bb.Magnitude > (dNeuralNetworkMagnitude*1.25) && + (fTestNet || (!fTestNet && pindexPrev->nHeight > 947000))) + { + return error("CheckProofOfResearch: Researchers block magnitude > neural network magnitude: Block Magnitude %f, Neural Network Magnitude %f, CPID %s ", + bb.Magnitude, dNeuralNetworkMagnitude, bb.cpid.c_str()); + } + + int64_t nCalculatedResearch = GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 1, block.nTime, + pindexBest, "checkblock_researcher", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); + + // TODO: Remove this tally? + if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) + { + BusyWaitForTally(); + StructCPID st1 = GetLifetimeCPID(bb.cpid,"CheckProofOfResearch()"); + nCalculatedResearch = GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 2, block.nTime, + pindexBest, "checkblock_researcher_doublecheck", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); + + if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) + { + if (fDebug3) printf("CheckProofOfResearch: Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", + bb.InterestSubsidy, bb.ResearchSubsidy, CoinToDouble(nCalculatedResearch), OUT_POR, OUT_INTEREST, bb.cpid.c_str()); + + return block.DoS(10,error("CheckProofOfResearch: Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", + bb.InterestSubsidy, bb.ResearchSubsidy,CoinToDouble(nCalculatedResearch), OUT_POR, OUT_INTEREST, bb.cpid.c_str())); + } + } + + return true; +} + // Return maximum amount of blocks that other nodes claim to have int GetNumBlocksOfPeers() { @@ -3818,104 +3875,68 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh if (bb.cpid != "INVESTOR" && IsProofOfStake() && height1 > nGrandfather && IsResearchAgeEnabled(height1) && BlockNeedsChecked(nTime) && !fLoadingIndex) { - // 6-4-2017 - Verify researchers stored block magnitude - double dNeuralNetworkMagnitude = CalculatedMagnitude2(bb.cpid, nTime, false); - if (bb.Magnitude > 0 && bb.Magnitude > (dNeuralNetworkMagnitude*1.25) && (fTestNet || (!fTestNet && height1 > 947000))) - { - return error("CheckBlock[ResearchAge] : Researchers block magnitude > neural network magnitude: Block Magnitude %f, Neural Network Magnitude %f, CPID %s ", - (double)bb.Magnitude,(double)dNeuralNetworkMagnitude,bb.cpid.c_str()); - } - int64_t nCalculatedResearch = GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 1, nTime, - pindexBest, sCaller + "_checkblock_researcher", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); - - - if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) - { - BusyWaitForTally(); - StructCPID st1 = GetLifetimeCPID(bb.cpid,"CheckBlock()"); - nCalculatedResearch = GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 2, nTime, - pindexBest, sCaller + "_checkblock_researcher_doublecheck", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); - - if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) - { - - if (fDebug3) printf("CheckBlock[ResearchAge] : Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", - (double)bb.InterestSubsidy,(double)bb.ResearchSubsidy,CoinToDouble(nCalculatedResearch),(double)OUT_POR,(double)OUT_INTEREST,bb.cpid.c_str()); - - return DoS(10,error("CheckBlock[ResearchAge] : Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", - (double)bb.InterestSubsidy,(double)bb.ResearchSubsidy,CoinToDouble(nCalculatedResearch),(double)OUT_POR,(double)OUT_INTEREST,bb.cpid.c_str())); - // Reserved for future use. - } - } + double blockVersion = BlockVersion(bb.clientversion); + double cvn = ClientVersionNew(); + if (fDebug10) printf("BV %f, CV %f ",blockVersion,cvn); + // Enforce Beacon Age + if (blockVersion < 3588 && height1 > 860500 && !fTestNet) + return error("CheckBlock[]: Old client spamming new blocks after mandatory upgrade \r\n"); + } + //Orphan Flood Attack + if (height1 > nGrandfather) + { + double bv = BlockVersion(bb.clientversion); + double cvn = ClientVersionNew(); + if (fDebug10) printf("BV %f, CV %f ",bv,cvn); + // Enforce Beacon Age + if (bv < 3588 && height1 > 860500 && !fTestNet) + return error("CheckBlock[]: Old client spamming new blocks after mandatory upgrade \r\n"); } - - //ProofOfResearch - if (vtx.size() > 0) + if (bb.cpid != "INVESTOR" && height1 > nGrandfather && BlockNeedsChecked(nTime)) { - //Orphan Flood Attack - if (height1 > nGrandfather) - { - double bv = BlockVersion(bb.clientversion); - double cvn = ClientVersionNew(); - if (fDebug10) printf("BV %f, CV %f ",bv,cvn); - // if (bv+10 < cvn) return error("ConnectBlock[]: Old client version after mandatory upgrade - block rejected\r\n"); - // Enforce Beacon Age - if (bv < 3588 && height1 > 860500 && !fTestNet) return error("CheckBlock[]: Old client spamming new blocks after mandatory upgrade \r\n"); - //if (bv < 3580 && fTestNet) return DoS(25, error("CheckBlock[]: Old testnet client spamming new blocks after mandatory upgrade \r\n")); - } + if (bb.projectname.empty() && !IsResearchAgeEnabled(height1)) + return DoS(1,error("CheckBlock::PoR Project Name invalid")); - if (bb.cpid != "INVESTOR" && height1 > nGrandfather && BlockNeedsChecked(nTime)) - { - if (bb.projectname.empty() && !IsResearchAgeEnabled(height1)) return DoS(1,error("CheckBlock::PoR Project Name invalid")); - if (!fLoadingIndex && !IsCPIDValidv2(bb,height1)) - { - std::string sOut2 = ""; - LoadAdminMessages(false,sOut2); - if (!fLoadingIndex && !IsCPIDValidv2(bb,height1)) - { - return error("Bad CPID or Block Signature : height %f, CPID %s, cpidv2 %s, LBH %s, Bad Hashboinc %s",(double)height1, - bb.cpid.c_str(), bb.cpidv2.c_str(), - bb.lastblockhash.c_str(), vtx[0].hashBoinc.c_str()); - } - } - - } - - // Gridcoin: check proof-of-stake block signature - if (IsProofOfStake() && height1 > nGrandfather) + if (!fLoadingIndex && !IsCPIDValidv2(bb,height1)) + { + std::string sOut2; + LoadAdminMessages(false,sOut2); + if (!fLoadingIndex && !IsCPIDValidv2(bb,height1)) { - //Mint limiter checks 1-20-2015 - double PORDiff = GetBlockDifficulty(nBits); - double mint1 = CoinToDouble(Mint); - double total_subsidy = bb.ResearchSubsidy + bb.InterestSubsidy; - double limiter = MintLimiter(PORDiff,bb.RSAWeight,bb.cpid,GetBlockTime()); - if (fDebug10) printf("CheckBlock[]: TotalSubsidy %f, Height %f, %s, %f, Res %f, Interest %f, hb: %s \r\n", - (double)total_subsidy,(double)height1, bb.cpid.c_str(), - (double)mint1,bb.ResearchSubsidy,bb.InterestSubsidy,vtx[0].hashBoinc.c_str()); - if (total_subsidy < limiter) - { - if (fDebug3) printf("****CheckBlock[]: Total Mint too Small %s, mint %f, Res %f, Interest %f, hash %s \r\n",bb.cpid.c_str(), - (double)mint1,bb.ResearchSubsidy,bb.InterestSubsidy,vtx[0].hashBoinc.c_str()); - //1-21-2015 - Prevent Hackers from spamming the network with small blocks - return error("****CheckBlock[]: Total Mint too Small %f < %f Research %f Interest %f BOINC %s", - total_subsidy,limiter,bb.ResearchSubsidy,bb.InterestSubsidy,vtx[0].hashBoinc.c_str()); - } - - if (fCheckSig && !CheckBlockSignature()) - return DoS(100, error("CheckBlock[] : bad proof-of-stake block signature")); + return error("Bad CPID or Block Signature : height %i, CPID %s, cpidv2 %s, LBH %s, Bad Hashboinc %s", height1, + bb.cpid.c_str(), bb.cpidv2.c_str(), + bb.lastblockhash.c_str(), vtx[0].hashBoinc.c_str()); } - - } - else + } + + // Gridcoin: check proof-of-stake block signature + if (IsProofOfStake() && height1 > nGrandfather) + { + //Mint limiter checks 1-20-2015 + double PORDiff = GetBlockDifficulty(nBits); + double mint1 = CoinToDouble(Mint); + double total_subsidy = bb.ResearchSubsidy + bb.InterestSubsidy; + double limiter = MintLimiter(PORDiff,bb.RSAWeight,bb.cpid,GetBlockTime()); + if (fDebug10) printf("CheckBlock[]: TotalSubsidy %f, Height %i, %s, %f, Res %f, Interest %f, hb: %s \r\n", + total_subsidy, height1, bb.cpid.c_str(), + mint1,bb.ResearchSubsidy,bb.InterestSubsidy,vtx[0].hashBoinc.c_str()); + if (total_subsidy < limiter) { - return false; + if (fDebug3) printf("****CheckBlock[]: Total Mint too Small %s, mint %f, Res %f, Interest %f, hash %s \r\n",bb.cpid.c_str(), + mint1,bb.ResearchSubsidy,bb.InterestSubsidy,vtx[0].hashBoinc.c_str()); + //1-21-2015 - Prevent Hackers from spamming the network with small blocks + return error("****CheckBlock[]: Total Mint too Small %f < %f Research %f Interest %f BOINC %s", + total_subsidy,limiter,bb.ResearchSubsidy,bb.InterestSubsidy,vtx[0].hashBoinc.c_str()); } - // End of Proof Of Research + if (fCheckSig && !CheckBlockSignature()) + return DoS(100, error("CheckBlock[] : bad proof-of-stake block signature")); + } + // End of Proof Of Research if (IsProofOfStake()) { // Coinbase output should be empty if proof-of-stake block @@ -3934,7 +3955,6 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh return DoS(100, error("CheckBlock[] : more than one coinstake")); } } - } // Check transactions @@ -4062,6 +4082,12 @@ bool CBlock::AcceptBlock(bool generated_by_me) } } + // Verify proof of research. + if(!CheckProofOfResearch(pindexPrev, *this)) + { + return error("WARNING: AcceptBlock(): check proof-of-research failed for block %s, nonce %i\n", hash.ToString().c_str(), nNonce); + } + // PoW is checked in CheckBlock[] if (IsProofOfWork()) { diff --git a/src/main.h b/src/main.h index 809a4f8160..d80ad095f4 100755 --- a/src/main.h +++ b/src/main.h @@ -247,6 +247,11 @@ double GetBlockDifficulty(unsigned int nBits); std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end); bool CheckProofOfWork(uint256 hash, unsigned int nBits); +// Validate researcher rewards. +bool CheckProofOfResearch( + const CBlockIndex* pindexPrev, //previous block in chain index + const CBlock &block); //block to check + unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake); int64_t GetProofOfWorkReward(int64_t nFees, int64_t locktime, int64_t height); From e86585922ca486a778428790becad03da7472d66 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 29 Sep 2017 08:54:25 +0200 Subject: [PATCH 081/166] Remove tally request rate limits. --- src/main.cpp | 21 +++------------------ src/main.h | 2 -- src/net.cpp | 12 +++++------- src/rpcblockchain.cpp | 1 - 4 files changed, 8 insertions(+), 28 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c155876b0e..45d2e59f65 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -147,11 +147,9 @@ CTxMemPool mempool; unsigned int nTransactionsUpdated = 0; unsigned int REORGANIZE_FAILED = 0; unsigned int WHITELISTED_PROJECTS = 0; -int64_t nLastTallied = 0; int64_t nLastPing = 0; int64_t nLastAskedForBlocks = 0; int64_t nBootup = 0; -int64_t nLastTallyBusyWait = 0; int64_t nLastTalliedNeural = 0; int64_t nLastLoadAdminMessages = 0; @@ -3251,7 +3249,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo if (fDebug3) printf("ConnectBlock(): Superblock Loaded %d \r\n", pindex->nHeight); /* Reserved for future use: bNetAveragesLoaded=false; - nLastTallied = 0; BsyWaitForTally(); */ if (!fColdBoot) @@ -5494,20 +5491,10 @@ bool TallyResearchAverages(bool Forcefully) return true; } - //if (Forcefully) nLastTallied = 0; - int timespan = fTestNet ? 2 : 6; - if (IsLockTimeWithinMinutes(nLastTallied,timespan)) - { - bNetAveragesLoaded=true; - return true; - } - //8-27-2016 - int64_t nStart = GetTimeMillis(); - + int64_t nStart = GetTimeMillis(); if (fDebug) printf("Tallying Research Averages (begin) "); - nLastTallied = GetAdjustedTime(); bNetAveragesLoaded = false; bool superblockloaded = false; double NetworkPayments = 0; @@ -5538,7 +5525,7 @@ bool TallyResearchAverages(bool Forcefully) if (fDebug3) printf("Max block %f, seektime %f",(double)pblockindex->nHeight,(double)GetTimeMillis()-nStart); nStart=GetTimeMillis(); - + // Headless critical section () try { @@ -5600,17 +5587,15 @@ bool TallyResearchAverages(bool Forcefully) { printf("Bad Alloc while tallying network averages. [1]\r\n"); bNetAveragesLoaded=true; - nLastTallied = 0; } catch(...) { printf("Error while tallying network averages. [1]\r\n"); bNetAveragesLoaded=true; - nLastTallied = 0; } if (fDebug3) printf("NA loaded in %f",(double)GetTimeMillis()-nStart); - + bNetAveragesLoaded=true; return false; } diff --git a/src/main.h b/src/main.h index d80ad095f4..5e1fff297d 100755 --- a/src/main.h +++ b/src/main.h @@ -159,7 +159,6 @@ extern bool bOPReturnEnabled; extern int64_t nTransactionFee; extern int64_t nReserveBalance; extern int64_t nMinimumInputValue; -extern int64_t nLastTallied; extern int64_t nLastPing; extern int64_t nLastAskedForBlocks; extern int64_t nBootup; @@ -167,7 +166,6 @@ extern int64_t nLastTalliedNeural; extern int64_t nCPIDsLoaded; extern int64_t nLastGRCtallied; extern int64_t nLastCleaned; -extern int64_t nLastTallyBusyWait; extern bool fUseFastIndex; extern unsigned int nDerivationMethodIndex; diff --git a/src/net.cpp b/src/net.cpp index 6f5ca89ec8..a26ccc6597 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1605,21 +1605,19 @@ void ThreadTallyResearchAverages(void* parg) void BusyWaitForTally() { - if (IsLockTimeWithinMinutes(nLastTallyBusyWait,10)) - { - return; - } if (fDebug10) printf("\r\n ** Busy Wait for Tally ** \r\n"); bTallyFinished=false; bDoTally=true; int iTimeout = 0; + + int64_t deadline = GetAdjustedTime() + 15000; while(!bTallyFinished) { - MilliSleep(1); + MilliSleep(10); + if(GetAdjustedTime() >= deadline) + break; iTimeout+=1; - if (iTimeout > 15000) break; } - nLastTallyBusyWait = GetAdjustedTime(); } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 069a584384..83b7fe1d5b 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -2047,7 +2047,6 @@ Value execute(const Array& params, bool fHelp) else if (sItem == "tally") { bNetAveragesLoaded = false; - nLastTallied = 0; TallyResearchAverages(true); entry.push_back(Pair("Tally Network Averages",1)); results.push_back(entry); From 01a31414ad49f49b15a3e50e0920e48f6c0bddd4 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 29 Sep 2017 09:37:32 +0200 Subject: [PATCH 082/166] Strict tally rules. Try to get a synchronized tally rate across the network by following strict tally rules: - Tally after loading blocks on startup - Tally on block height % 60 == 0 - Tally after reorganize This should fix research reward errors due to tally desync, #245 and #641. This also removes the need for a separate tally thread and a busy sleep. --- src/global_objects_noui.hpp | 2 - src/init.cpp | 11 +- src/main.cpp | 248 +++++++++++++++--------------------- src/net.cpp | 84 ------------ src/rpcblockchain.cpp | 8 -- 5 files changed, 108 insertions(+), 245 deletions(-) diff --git a/src/global_objects_noui.hpp b/src/global_objects_noui.hpp index 724c99b8c4..182d7b11f5 100755 --- a/src/global_objects_noui.hpp +++ b/src/global_objects_noui.hpp @@ -14,8 +14,6 @@ extern bool bForceUpdate; extern bool bCheckedForUpgrade; extern bool bCheckedForUpgradeLive; extern bool bGlobalcomInitialized; -extern bool bDoTally; -extern bool bTallyFinished; extern bool bGridcoinGUILoaded; struct StructCPID diff --git a/src/init.cpp b/src/init.cpp index 144f6bb80f..eaf5fbadc1 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -24,7 +24,8 @@ bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); StructCPID GetStructCPID(); bool ComputeNeuralNetworkSupermajorityHashes(); -void BusyWaitForTally(); +void TallyNetworkAverages(); +extern void ThreadAppInit2(void* parg); void LoadCPIDsInBackground(); bool IsConfigFileEmpty(); @@ -992,12 +993,12 @@ bool AppInit2(ThreadHandlerPtr threads) } - uiInterface.InitMessage(_("Loading Network Averages...")); + uiInterface.InitMessage(_("Loading Network Averages...")); if (fDebug3) printf("Loading network averages"); - if (!threads->createThread(StartNode, NULL, "Start Thread")) + TallyNetworkAverages(); - InitError(_("Error: could not start node")); - BusyWaitForTally(); + if (!threads->createThread(StartNode, NULL, "Start Thread")) + InitError(_("Error: could not start node")); if (fServer) threads->createThread(ThreadRPCServer, NULL, "RPC Server Thread"); diff --git a/src/main.cpp b/src/main.cpp index 45d2e59f65..66b6e09595 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,7 +51,7 @@ bool RequestSupermajorityNeuralData(); extern bool AskForOutstandingBlocks(uint256 hashStart); extern bool CleanChain(); extern void ResetTimerMain(std::string timer_name); -extern bool TallyResearchAverages(bool Forcefully); +extern bool TallyResearchAverages(); extern void IncrementCurrentNeuralNetworkSupermajority(std::string NeuralHash, std::string GRCAddress, double distance); bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature); int DetermineCPIDType(std::string cpid); @@ -62,8 +62,7 @@ extern double ExtractMagnitudeFromExplainMagnitude(); extern void GridcoinServices(); extern double SnapToGrid(double d); extern bool StrLessThanReferenceHash(std::string rh); -void BusyWaitForTally(); -extern bool TallyNetworkAverages(bool Forcefully); +extern bool TallyNetworkAverages(); extern bool IsContract(CBlockIndex* pIndex); std::string ExtractValue(std::string data, std::string delimiter, int pos); extern MiningCPID GetBoincBlockByIndex(CBlockIndex* pblockindex); @@ -261,8 +260,6 @@ bool bCheckedForUpgrade = false; bool bCheckedForUpgradeLive = false; bool bGlobalcomInitialized = false; bool bStakeMinerOutOfSyncWithNetwork = false; -bool bDoTally = false; -bool bTallyFinished = false; bool bGridcoinGUILoaded = false; extern double LederstrumpfMagnitude2(double Magnitude, int64_t locktime); @@ -2184,19 +2181,11 @@ bool CheckProofOfResearch( // TODO: Remove this tally? if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) { - BusyWaitForTally(); - StructCPID st1 = GetLifetimeCPID(bb.cpid,"CheckProofOfResearch()"); - nCalculatedResearch = GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 2, block.nTime, - pindexBest, "checkblock_researcher_doublecheck", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); + if (fDebug3) printf("CheckProofOfResearch: Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", + bb.InterestSubsidy, bb.ResearchSubsidy, CoinToDouble(nCalculatedResearch), OUT_POR, OUT_INTEREST, bb.cpid.c_str()); - if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) - { - if (fDebug3) printf("CheckProofOfResearch: Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", - bb.InterestSubsidy, bb.ResearchSubsidy, CoinToDouble(nCalculatedResearch), OUT_POR, OUT_INTEREST, bb.cpid.c_str()); - - return block.DoS(10,error("CheckProofOfResearch: Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", - bb.InterestSubsidy, bb.ResearchSubsidy,CoinToDouble(nCalculatedResearch), OUT_POR, OUT_INTEREST, bb.cpid.c_str())); - } + return block.DoS(10,error("CheckProofOfResearch: Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", + bb.InterestSubsidy, bb.ResearchSubsidy,CoinToDouble(nCalculatedResearch), OUT_POR, OUT_INTEREST, bb.cpid.c_str())); } return true; @@ -3146,7 +3135,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo { if (bb.ResearchSubsidy > (GetOwedAmount(bb.cpid)+1)) { - bDoTally=true; if (bb.ResearchSubsidy > (GetOwedAmount(bb.cpid)+1)) { StructCPID strUntrustedHost = GetInitializedStructCPID2(bb.cpid,mvMagnitudes); @@ -3247,14 +3235,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo { LoadSuperblock(superblock,pindex->nTime,pindex->nHeight); if (fDebug3) printf("ConnectBlock(): Superblock Loaded %d \r\n", pindex->nHeight); - /* Reserved for future use: - bNetAveragesLoaded=false; - BsyWaitForTally(); - */ - if (!fColdBoot) - { - bDoTally = true; - } } else { @@ -3307,18 +3287,9 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo LoadAdminMessages(false,errors1); } - // Slow down Retallying when in RA mode so we minimize disruption of the network - if ( (pindex->nHeight % 60 == 0) && IsResearchAgeEnabled(pindex->nHeight) && BlockNeedsChecked(pindex->nTime)) + if (IsResearchAgeEnabled(pindex->nHeight) && !OutOfSyncByAge()) { - if (fDebug3) printf("\r\n*BusyWaitForTally*\r\n"); - BusyWaitForTally(); - } - - - if (IsResearchAgeEnabled(pindex->nHeight) && !OutOfSyncByAge()) - { - fColdBoot = false; - bDoTally=true; + fColdBoot = false; } if (fJustCheck) @@ -3603,8 +3574,8 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) printf("Failed to Reorganize during Attempt #%f \r\n",(double)iRegression+1); txdb.TxnAbort(); InvalidChainFound(pindexNew); - printf("\r\nReorg BusyWait\r\n"); - BusyWaitForTally(); + printf("\r\nReorg tally\r\n"); + TallyNetworkAverages(); REORGANIZE_FAILED++; return error("SetBestChain() : Reorganize failed"); } @@ -3862,14 +3833,6 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh //Research Age MiningCPID bb = DeserializeBoincBlock(vtx[0].hashBoinc,nVersion); //For higher security, plus lets catch these bad blocks before adding them to the chain to prevent reorgs: - double OUT_POR = 0; - double OUT_INTEREST = 0; - double dAccrualAge = 0; - double dMagnitudeUnit = 0; - double dAvgMagnitude = 0; - uint64_t nCoinAge = 0; - int64_t nFees = 0; - if (bb.cpid != "INVESTOR" && IsProofOfStake() && height1 > nGrandfather && IsResearchAgeEnabled(height1) && BlockNeedsChecked(nTime) && !fLoadingIndex) { double blockVersion = BlockVersion(bb.clientversion); @@ -4329,11 +4292,6 @@ void GridcoinServices() ComputeNeuralNetworkSupermajorityHashes(); UpdateNeuralNetworkQuorumData(); } - if ((nBestHeight % 20) == 0) - { - if (fDebug10) printf("#TIB# "); - bDoTally = true; - } } else { @@ -4341,10 +4299,8 @@ void GridcoinServices() int nTallyGranularity = fTestNet ? 60 : 20; if ((nBestHeight % nTallyGranularity) == 0) { - if (fDebug3) printf("TIB1 "); - bDoTally = true; - if (fDebug3) printf("CNNSH2 "); - ComputeNeuralNetworkSupermajorityHashes(); + TallyNetworkAverages(); + ComputeNeuralNetworkSupermajorityHashes(); } if ((nBestHeight % 5)==0) @@ -5482,8 +5438,8 @@ bool ComputeNeuralNetworkSupermajorityHashes() } -bool TallyResearchAverages(bool Forcefully) -{ +bool TallyResearchAverages() +{ //Iterate throught last 14 days, tally network averages if (nBestHeight < 15) { @@ -5500,113 +5456,113 @@ bool TallyResearchAverages(bool Forcefully) double NetworkPayments = 0; double NetworkInterest = 0; - //Consensus Start/End block: - int nMaxDepth = (nBestHeight-CONSENSUS_LOOKBACK) - ( (nBestHeight-CONSENSUS_LOOKBACK) % BLOCK_GRANULARITY); - int nLookback = BLOCKS_PER_DAY * 14; //Daily block count * Lookback in days - int nMinDepth = (nMaxDepth - nLookback) - ( (nMaxDepth-nLookback) % BLOCK_GRANULARITY); - if (fDebug3) printf("START BLOCK %f, END BLOCK %f ",(double)nMaxDepth,(double)nMinDepth); - if (nMinDepth < 2) nMinDepth = 2; - mvMagnitudesCopy.clear(); - int iRow = 0; - //CBlock block; - CBlockIndex* pblockindex = pindexBest; - if (!pblockindex) - { - bTallyStarted = false; - bNetAveragesLoaded = true; - return true; - } - while (pblockindex->nHeight > nMaxDepth) - { - if (!pblockindex || !pblockindex->pprev || pblockindex == pindexGenesisBlock) return false; - pblockindex = pblockindex->pprev; - } + //Consensus Start/End block: + int nMaxDepth = (nBestHeight-CONSENSUS_LOOKBACK) - ( (nBestHeight-CONSENSUS_LOOKBACK) % BLOCK_GRANULARITY); + int nLookback = BLOCKS_PER_DAY * 14; //Daily block count * Lookback in days + int nMinDepth = (nMaxDepth - nLookback) - ( (nMaxDepth-nLookback) % BLOCK_GRANULARITY); + if (fDebug3) printf("START BLOCK %f, END BLOCK %f ",(double)nMaxDepth,(double)nMinDepth); + if (nMinDepth < 2) nMinDepth = 2; + mvMagnitudesCopy.clear(); + int iRow = 0; + //CBlock block; + CBlockIndex* pblockindex = pindexBest; + if (!pblockindex) + { + bTallyStarted = false; + bNetAveragesLoaded = true; + return true; + } + while (pblockindex->nHeight > nMaxDepth) + { + if (!pblockindex || !pblockindex->pprev || pblockindex == pindexGenesisBlock) return false; + pblockindex = pblockindex->pprev; + } - if (fDebug3) printf("Max block %f, seektime %f",(double)pblockindex->nHeight,(double)GetTimeMillis()-nStart); - nStart=GetTimeMillis(); + if (fDebug3) printf("Max block %f, seektime %f",(double)pblockindex->nHeight,(double)GetTimeMillis()-nStart); + nStart=GetTimeMillis(); - // Headless critical section () - try + // Headless critical section () + try + { + while (pblockindex->nHeight > nMinDepth) { - while (pblockindex->nHeight > nMinDepth) - { - if (!pblockindex || !pblockindex->pprev) return false; - pblockindex = pblockindex->pprev; - if (pblockindex == pindexGenesisBlock) return false; - if (!pblockindex->IsInMainChain()) continue; - NetworkPayments += pblockindex->nResearchSubsidy; - NetworkInterest += pblockindex->nInterestSubsidy; - AddResearchMagnitude(pblockindex); + if (!pblockindex || !pblockindex->pprev) return false; + pblockindex = pblockindex->pprev; + if (pblockindex == pindexGenesisBlock) return false; + if (!pblockindex->IsInMainChain()) continue; + NetworkPayments += pblockindex->nResearchSubsidy; + NetworkInterest += pblockindex->nInterestSubsidy; + AddResearchMagnitude(pblockindex); - iRow++; - if (IsSuperBlock(pblockindex) && !superblockloaded) - { - MiningCPID bb = GetBoincBlockByIndex(pblockindex); - if (bb.superblock.length() > 20) - { - std::string superblock = UnpackBinarySuperblock(bb.superblock); - if (VerifySuperblock(superblock, pblockindex)) - { - LoadSuperblock(superblock,pblockindex->nTime,pblockindex->nHeight); - superblockloaded=true; - if (fDebug) - printf(" Superblock Loaded %i", pblockindex->nHeight); - } - } - } + iRow++; + if (IsSuperBlock(pblockindex) && !superblockloaded) + { + MiningCPID bb = GetBoincBlockByIndex(pblockindex); + if (bb.superblock.length() > 20) + { + std::string superblock = UnpackBinarySuperblock(bb.superblock); + if (VerifySuperblock(superblock, pblockindex)) + { + LoadSuperblock(superblock,pblockindex->nTime,pblockindex->nHeight); + superblockloaded=true; + if (fDebug) + printf(" Superblock Loaded %i", pblockindex->nHeight); + } + } + } - } - // End of critical section - if (fDebug3) printf("TNA loaded in %" PRId64, GetTimeMillis()-nStart); - nStart=GetTimeMillis(); + } + // End of critical section + if (fDebug3) printf("TNA loaded in %" PRId64, GetTimeMillis()-nStart); + nStart=GetTimeMillis(); - if (pblockindex) - { - if (fDebug3) - printf("Min block %i, Rows %i", pblockindex->nHeight, iRow); - - StructCPID network = GetInitializedStructCPID2("NETWORK",mvNetworkCopy); - network.projectname="NETWORK"; - network.payments = NetworkPayments; - network.InterestSubsidy = NetworkInterest; - mvNetworkCopy["NETWORK"] = network; - if(fDebug3) printf(" TMIS1 "); - TallyMagnitudesInSuperblock(); - } - // 11-19-2015 Copy dictionaries to live RAM - mvDPOR = mvDPORCopy; - mvMagnitudes = mvMagnitudesCopy; - mvNetwork = mvNetworkCopy; - bTallyStarted = false; - bNetAveragesLoaded = true; - return true; - } - catch (bad_alloc ba) - { - printf("Bad Alloc while tallying network averages. [1]\r\n"); - bNetAveragesLoaded=true; - } - catch(...) + if (pblockindex) { - printf("Error while tallying network averages. [1]\r\n"); - bNetAveragesLoaded=true; + if (fDebug3) + printf("Min block %i, Rows %i", pblockindex->nHeight, iRow); + + StructCPID network = GetInitializedStructCPID2("NETWORK",mvNetworkCopy); + network.projectname="NETWORK"; + network.payments = NetworkPayments; + network.InterestSubsidy = NetworkInterest; + mvNetworkCopy["NETWORK"] = network; + if(fDebug3) printf(" TMIS1 "); + TallyMagnitudesInSuperblock(); } + // 11-19-2015 Copy dictionaries to live RAM + mvDPOR = mvDPORCopy; + mvMagnitudes = mvMagnitudesCopy; + mvNetwork = mvNetworkCopy; + bTallyStarted = false; + bNetAveragesLoaded = true; + return true; + } + catch (bad_alloc ba) + { + printf("Bad Alloc while tallying network averages. [1]\r\n"); + bNetAveragesLoaded=true; + } + catch(...) + { + printf("Error while tallying network averages. [1]\r\n"); + bNetAveragesLoaded=true; + } - if (fDebug3) printf("NA loaded in %f",(double)GetTimeMillis()-nStart); + if (fDebug3) printf("NA loaded in %f",(double)GetTimeMillis()-nStart); - bNetAveragesLoaded=true; - return false; + bNetAveragesLoaded=true; + return false; } -bool TallyNetworkAverages(bool Forcefully) +bool TallyNetworkAverages() { if (IsResearchAgeEnabled(pindexBest->nHeight)) { - return TallyResearchAverages(Forcefully); + return TallyResearchAverages(); } return false; diff --git a/src/net.cpp b/src/net.cpp index a26ccc6597..fe3ae1b07c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -26,8 +26,6 @@ #endif using namespace std; -bool TallyNetworkAverages(bool ColdBoot); -extern void DoTallyResearchAverages(void* parg); std::string DefaultWalletAddress(); std::string NodeAddress(CNode* pfrom); @@ -1573,84 +1571,6 @@ void DumpAddresses() } -void ThreadTallyResearchAverages(void* parg) -{ - // Make this thread recognisable - RenameThread("grc-tallyresearchaverages"); - -begin: - try - { - DoTallyResearchAverages(parg); - } - catch (std::exception& e) - { - PrintException(&e, "ThreadTallyNetworkAverages()"); - } - catch(boost::thread_interrupted&) - { - printf("ThreadTallyResearchAverages exited (interrupt)\r\n"); - return; - } - catch(...) - { - printf("Error in ThreadTallyResearchAverages... Recovering \r\n"); - } - MilliSleep(10000); - if (!fShutdown) printf("Thread TallyReasearchAverages exited, Restarting.. \r\n"); - if (!fShutdown) goto begin; - printf("ThreadTallyResearchAverages exited \r\n"); -} - - -void BusyWaitForTally() -{ - if (fDebug10) printf("\r\n ** Busy Wait for Tally ** \r\n"); - bTallyFinished=false; - bDoTally=true; - int iTimeout = 0; - - int64_t deadline = GetAdjustedTime() + 15000; - while(!bTallyFinished) - { - MilliSleep(10); - if(GetAdjustedTime() >= deadline) - break; - iTimeout+=1; - } -} - - -void DoTallyResearchAverages(void* parg) -{ - printf("\r\nStarting dedicated Tally thread...\r\n"); - - while (!fShutdown) - { - MilliSleep(100); - if (bDoTally) - { - bTallyFinished = false; - bDoTally=false; - printf("\r\n[DoTallyRA_START] "); - try - { - TallyNetworkAverages(false); - } - catch (std::exception& e) - { - PrintException(&e, "ThreadTallyNetworkAverages()"); - } - catch(...) - { - printf("\r\nError occurred in DoTallyResearchAverages...Recovering\r\n"); - } - printf(" [DoTallyRA_END] \r\n"); - bTallyFinished = true; - } - } -} - void ThreadDumpAddress2(void* parg) { while (!fShutdown) @@ -2320,10 +2240,6 @@ void StartNode(void* parg) // Dump network addresses if (!netThreads->createThread(ThreadDumpAddress,NULL,"ThreadDumpAddress")) printf("Error: createThread(ThreadDumpAddress) failed\r\n"); - - // Tally network averages - if (!NewThread(ThreadTallyResearchAverages, NULL)) - printf("Error; NewThread(ThreadTally) failed\n"); // Mine proof-of-stake blocks in the background if (!GetBoolArg("-staking", true)) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 83b7fe1d5b..262c809027 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -42,7 +42,6 @@ extern Array MagnitudeReport(std::string cpid); std::string ConvertBinToHex(std::string a); std::string ConvertHexToBin(std::string a); extern std::vector readFileToVector(std::string filename); -bool TallyResearchAverages(bool Forcefully); int RestartClient(); extern std::string SignBlockWithCPID(std::string sCPID, std::string sBlockHash); std::string BurnCoinsWithNewContract(bool bAdd, std::string sType, std::string sPrimaryKey, std::string sValue, int64_t MinimumBalance, double dFees, std::string strPublicKey, std::string sBurnAddress); @@ -2044,13 +2043,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("Requested a quorum - waiting for resolution.",1)); results.push_back(entry); } - else if (sItem == "tally") - { - bNetAveragesLoaded = false; - TallyResearchAverages(true); - entry.push_back(Pair("Tally Network Averages",1)); - results.push_back(entry); - } else if (sItem == "encrypt") { //Encrypt a phrase From 58321706ad391b97610e5fddde584ff1af195139 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 29 Sep 2017 09:58:31 +0200 Subject: [PATCH 083/166] Remove superblock loading from testnewcontract RPC. --- src/rpcblockchain.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 262c809027..2d9e559e0e 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -2016,7 +2016,6 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("My Neural Hash",myNeuralHash.c_str())); results.push_back(entry); #endif - LoadSuperblock(contract,GetAdjustedTime(),280000); entry.push_back(Pair("Contract Test",contract)); // Convert to Binary std::string sBin = PackBinarySuperblock(contract); From 4bb3305d09fd4bc1920895adb61bc2ede5bfd70c Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 29 Sep 2017 10:10:06 +0200 Subject: [PATCH 084/166] Bump the grandfather block. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 66b6e09595..834571f9e7 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -310,7 +310,7 @@ std::string msNeuralResponse; std::string msHDDSerial; //When syncing, we grandfather block rejection rules up to this block, as rules became stricter over time and fields changed -int nGrandfather = 1034700; +int nGrandfather = 1035000; int nNewIndex = 271625; int nNewIndex2 = 364500; From 817283016569c5ea403ab288dd906c62f772211e Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 7 Oct 2017 15:39:59 +0200 Subject: [PATCH 085/166] Remove stray whitespaces. --- src/init.cpp | 4 ++-- src/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index eaf5fbadc1..176cf31462 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -993,12 +993,12 @@ bool AppInit2(ThreadHandlerPtr threads) } - uiInterface.InitMessage(_("Loading Network Averages...")); + uiInterface.InitMessage(_("Loading Network Averages...")); if (fDebug3) printf("Loading network averages"); TallyNetworkAverages(); if (!threads->createThread(StartNode, NULL, "Start Thread")) - InitError(_("Error: could not start node")); + InitError(_("Error: could not start node")); if (fServer) threads->createThread(ThreadRPCServer, NULL, "RPC Server Thread"); diff --git a/src/main.cpp b/src/main.cpp index 834571f9e7..406c7b7a95 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5439,7 +5439,7 @@ bool ComputeNeuralNetworkSupermajorityHashes() bool TallyResearchAverages() -{ +{ //Iterate throught last 14 days, tally network averages if (nBestHeight < 15) { From 6fbcf25809f03a4d5588a856674f218e677a0283 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 8 Oct 2017 17:19:18 +0200 Subject: [PATCH 086/166] Remove unused bTallyStarted. --- src/main.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 406c7b7a95..47c444955e 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -254,7 +254,6 @@ extern std::string RetrieveMd5(std::string s1); extern std::string aes_complex_hash(uint256 scrypt_hash); bool bNetAveragesLoaded = false; -bool bTallyStarted = false; bool bForceUpdate = false; bool bCheckedForUpgrade = false; bool bCheckedForUpgradeLive = false; @@ -4235,11 +4234,6 @@ void GridcoinServices() printf("Daily backup results: Wallet -> %s Config -> %s\r\n", (bWalletBackupResults ? "true" : "false"), (bConfigBackupResults ? "true" : "false")); } - if (TimerMain("ResetVars",30)) - { - bTallyStarted = false; - } - if (false && TimerMain("FixSpentCoins",60)) { int nMismatchSpent; @@ -5464,11 +5458,10 @@ bool TallyResearchAverages() if (nMinDepth < 2) nMinDepth = 2; mvMagnitudesCopy.clear(); int iRow = 0; - //CBlock block; + CBlockIndex* pblockindex = pindexBest; if (!pblockindex) { - bTallyStarted = false; bNetAveragesLoaded = true; return true; } @@ -5535,7 +5528,6 @@ bool TallyResearchAverages() mvDPOR = mvDPORCopy; mvMagnitudes = mvMagnitudesCopy; mvNetwork = mvNetworkCopy; - bTallyStarted = false; bNetAveragesLoaded = true; return true; } From 949d96355fbb7fc26c950f234b4945fa8cb5df22 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 21 Oct 2017 08:02:10 +0200 Subject: [PATCH 087/166] Disconnect tallying from superblock requirements. Also simplify quorum collections to always trigger every 3 blocks regardless of the current superblock state. Needs testing. --- src/main.cpp | 40 ++++++++-------------------------------- src/main.h | 3 ++- 2 files changed, 10 insertions(+), 33 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 47c444955e..26c6c4addb 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4269,41 +4269,17 @@ void GridcoinServices() } } - int64_t superblock_age = GetAdjustedTime() - mvApplicationCacheTimestamp["superblock;magnitudes"]; - bool bNeedSuperblock = (superblock_age > (GetSuperblockAgeSpacing(nBestHeight))); - if ( nBestHeight % 3 == 0 && NeedASuperblock() ) bNeedSuperblock=true; - - if (fDebug10) + // Update quorum data. + if ((nBestHeight % 3) == 0) { - printf (" MRSA %" PRId64 ", BH %d", superblock_age, nBestHeight); - } - - if (bNeedSuperblock) - { - if ((nBestHeight % 3) == 0) - { - if (fDebug10) printf("#CNNSH# "); - ComputeNeuralNetworkSupermajorityHashes(); - UpdateNeuralNetworkQuorumData(); - } - } - else - { - // When superblock is not old, Tally every N mins: - int nTallyGranularity = fTestNet ? 60 : 20; - if ((nBestHeight % nTallyGranularity) == 0) - { - TallyNetworkAverages(); - ComputeNeuralNetworkSupermajorityHashes(); - } - - if ((nBestHeight % 5)==0) - { - UpdateNeuralNetworkQuorumData(); - } - + ComputeNeuralNetworkSupermajorityHashes(); + UpdateNeuralNetworkQuorumData(); } + // Tally research averages. + if ((nBestHeight % TALLY_GRANULARITY) == 0) + TallyNetworkAverages(); + // Every N blocks as a Synchronized TEAM: if ((nBestHeight % 30) == 0) { diff --git a/src/main.h b/src/main.h index 5e1fff297d..fa03b0e8b0 100755 --- a/src/main.h +++ b/src/main.h @@ -30,7 +30,8 @@ static const int LAST_POW_BLOCK = 2050; extern unsigned int REORGANIZE_FAILED; extern unsigned int WHITELISTED_PROJECTS; static const int CONSENSUS_LOOKBACK = 5; //Amount of blocks to go back from best block, to avoid counting forked blocks -static const int BLOCK_GRANULARITY = 10; //Consensus block divisor +static const int BLOCK_GRANULARITY = 10; //Consensus block divisor +static const int TALLY_GRANULARITY = BLOCK_GRANULARITY; static const double NeuralNetworkMultiplier = 115000; From 066bcdf738866c8614b391b9c96525b5877b0d82 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 21 Oct 2017 08:13:44 +0200 Subject: [PATCH 088/166] Simplify tally range calculations. --- src/main.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 26c6c4addb..ce80cbe308 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5427,11 +5427,14 @@ bool TallyResearchAverages() double NetworkInterest = 0; //Consensus Start/End block: - int nMaxDepth = (nBestHeight-CONSENSUS_LOOKBACK) - ( (nBestHeight-CONSENSUS_LOOKBACK) % BLOCK_GRANULARITY); + int nMaxConensusDepth = nBestHeight - CONSENSUS_LOOKBACK; + int nMaxDepth = nMaxConensusDepth - (nMaxConensusDepth % TALLY_GRANULARITY); int nLookback = BLOCKS_PER_DAY * 14; //Daily block count * Lookback in days - int nMinDepth = (nMaxDepth - nLookback) - ( (nMaxDepth-nLookback) % BLOCK_GRANULARITY); - if (fDebug3) printf("START BLOCK %f, END BLOCK %f ",(double)nMaxDepth,(double)nMinDepth); - if (nMinDepth < 2) nMinDepth = 2; + int nMinDepth = nMaxDepth - nLookback; + if (nMinDepth < 2) + nMinDepth = 2; + + if (fDebug3) printf("START BLOCK %i, END BLOCK %i", nMaxDepth, nMinDepth); mvMagnitudesCopy.clear(); int iRow = 0; From b495b19488becf401a78f7983d62c9e316a5565c Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 24 Oct 2017 07:09:32 +0200 Subject: [PATCH 089/166] Remove commented out code. --- src/miner.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 8b0a3dbb10..71830adfad 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -32,7 +32,6 @@ void ThreadTopUpKeyPool(void* parg); std::string SerializeBoincBlock(MiningCPID mcpid); bool LessVerbose(int iMax1000); -double CalculatedMagnitude2(std::string cpid, int64_t locktime,bool bUseLederstrumpf); int64_t GetRSAWeightByBlock(MiningCPID boincblock); std::string SignBlockWithCPID(std::string sCPID, std::string sBlockHash); std::string qtGetNeuralContract(std::string data); @@ -727,20 +726,6 @@ bool CreateGridcoinReward(CBlock &blocknew, MiningCPID& miningcpid, uint64_t &nC uint256 pbh = 0; pbh=pindexPrev->GetBlockHash(); - /* This is should be already done in GetNextProject - miningcpid.cpidv2 = ComputeCPIDv2( - GlobalCPUMiningCPID.email, - GlobalCPUMiningCPID.boincruntimepublickey, - pbh ); - - - miningcpid.Magnitude = CalculatedMagnitude2( - GlobalCPUMiningCPID.cpid, blocknew.nTime, - false ); - - miningcpid.RSAWeight = GetRSAWeightByCPID(GlobalCPUMiningCPID.cpid); - */ - miningcpid.lastblockhash = pbh.GetHex(); miningcpid.ResearchSubsidy = OUT_POR; miningcpid.ResearchSubsidy2 = OUT_POR; From 1c92c2e9810933c9c1e1d751c60646a9866c2291 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 24 Oct 2017 07:09:43 +0200 Subject: [PATCH 090/166] Remove PoW check which cannot happen anymore. --- src/main.cpp | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ce80cbe308..7afbba4539 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1794,21 +1794,6 @@ int64_t GetProofOfWorkReward(int64_t nFees, int64_t locktime, int64_t height) return nSubsidy + nFees; } - -int64_t GetProofOfWorkMaxReward(int64_t nFees, int64_t locktime, int64_t height) -{ - int64_t nSubsidy = (GetMaximumBoincSubsidy(locktime)+1) * COIN; - if (height==10) - { - //R.Halford: 10-11-2014: Gridcoin Foundation Block: - //Note: Gridcoin Classic emitted these coins. So we had to add them to block 10. The coins were burned then given back to the owners that mined them in classic (as research coins). - nSubsidy = nGenesisSupply * COIN; - } - - if (fTestNet) nSubsidy += 1000*COIN; - return nSubsidy + nFees; -} - //Survey Results: Start inflation rate: 9%, end=1%, 30 day steps, 9 steps, mag multiplier start: 2, mag end .3, 9 steps int64_t GetMaximumBoincSubsidy(int64_t nTime) { @@ -2967,16 +2952,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size()); } - if (IsProofOfWork() && pindex->nHeight > nGrandfather) - { - int64_t nReward = GetProofOfWorkMaxReward(nFees,nTime,pindex->nHeight); - // Check coinbase reward - if (vtx[0].GetValueOut() > nReward) - return DoS(50, error("ConnectBlock[] : coinbase reward exceeded (actual=%" PRId64 " vs calculated=%" PRId64 ")", - vtx[0].GetValueOut(), - nReward)); - } - MiningCPID bb = DeserializeBoincBlock(vtx[0].hashBoinc,nVersion); uint64_t nCoinAge = 0; From 2f84f3262aa202890d1d5412b00192716efecc25 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 24 Oct 2017 12:40:12 +0200 Subject: [PATCH 091/166] Remove unused nTransactionsUpdated. --- src/init.cpp | 1 - src/main.cpp | 5 ----- src/main.h | 1 - src/net.cpp | 1 - 4 files changed, 8 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 176cf31462..922ce3a154 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -92,7 +92,6 @@ void Shutdown(void* parg) printf("gridcoinresearch exiting...\r\n"); fShutdown = true; - nTransactionsUpdated++; bitdb.Flush(false); StopNode(); bitdb.Flush(true); diff --git a/src/main.cpp b/src/main.cpp index 7afbba4539..bc9b6a6fbf 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -143,7 +143,6 @@ CCriticalSection cs_main; extern std::string NodeAddress(CNode* pfrom); CTxMemPool mempool; -unsigned int nTransactionsUpdated = 0; unsigned int REORGANIZE_FAILED = 0; unsigned int WHITELISTED_PROJECTS = 0; int64_t nLastPing = 0; @@ -1525,7 +1524,6 @@ bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx) mapTx[hash] = tx; for (unsigned int i = 0; i < tx.vin.size(); i++) mapNextTx[tx.vin[i].prevout] = CInPoint(&mapTx[hash], i); - nTransactionsUpdated++; } return true; } @@ -1549,7 +1547,6 @@ bool CTxMemPool::remove(const CTransaction &tx, bool fRecursive) for (auto const& txin : tx.vin) mapNextTx.erase(txin.prevout); mapTx.erase(hash); - nTransactionsUpdated++; } } return true; @@ -1576,7 +1573,6 @@ void CTxMemPool::clear() LOCK(cs); mapTx.clear(); mapNextTx.clear(); - ++nTransactionsUpdated; } void CTxMemPool::queryHashes(std::vector& vtxid) @@ -3591,7 +3587,6 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) nBestHeight = pindexBest->nHeight; nBestChainTrust = pindexNew->nChainTrust; nTimeBestReceived = GetAdjustedTime(); - nTransactionsUpdated++; uint256 nBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->nChainTrust - pindexBest->pprev->nChainTrust) : pindexBest->nChainTrust; diff --git a/src/main.h b/src/main.h index fa03b0e8b0..a1b91626ac 100755 --- a/src/main.h +++ b/src/main.h @@ -146,7 +146,6 @@ extern uint256 nBestChainTrust; extern uint256 nBestInvalidTrust; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; -extern unsigned int nTransactionsUpdated; extern const std::string strMessageMagic; extern int64_t nTimeBestReceived; extern CCriticalSection cs_setpwalletRegistered; diff --git a/src/net.cpp b/src/net.cpp index fe3ae1b07c..9709bc77d2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2253,7 +2253,6 @@ bool StopNode() { printf("StopNode()\n"); fShutdown = true; - nTransactionsUpdated++; if (semOutbound) for (int i=0; ipost(); From 1c671cf043dde5dc0670f3393d9fa0e510a196a3 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 24 Oct 2017 12:41:01 +0200 Subject: [PATCH 092/166] Don't reverse vSortedByTimestamp if we're going to sort it. --- src/kernel.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index 9645b47f06..37f0f77e7d 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -165,8 +165,7 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod pindex = pindex->pprev; } int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0; - reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); - sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); + std::sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); // Select 64 blocks from candidate blocks to generate stake modifier uint64_t nStakeModifierNew = 0; From 4755eeebbb979e0c9f3aa1030300f3551475cec6 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 24 Oct 2017 13:12:46 +0200 Subject: [PATCH 093/166] Slightly more efficient mapBlockIndex usage. Instead of counting items and then accessing, thus causing two map searches instead of one, just use the result of a find operation instead. --- src/kernel.cpp | 10 ++++++---- src/main.cpp | 22 ++++++++++++++-------- src/wallet.cpp | 5 +++-- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index 37f0f77e7d..6148eba2fc 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -76,9 +76,10 @@ static bool SelectBlockFromCandidates(vector >& vSortedBy *pindexSelected = (const CBlockIndex*) 0; for (auto const& item : vSortedByTimestamp) { - if (!mapBlockIndex.count(item.second)) + const auto mapItem = mapBlockIndex.find(item.second); + if (mapItem == mapBlockIndex.end()) return error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString().c_str()); - const CBlockIndex* pindex = mapBlockIndex[item.second]; + const CBlockIndex* pindex = mapItem->second; if (fSelected && pindex->GetBlockTime() > nSelectionIntervalStop) break; if (mapSelectedBlocks.count(pindex->GetBlockHash()) > 0) @@ -224,9 +225,10 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake) { nStakeModifier = 0; - if (!mapBlockIndex.count(hashBlockFrom)) + const auto mapItem = mapBlockIndex.find(hashBlockFrom); + if (mapItem == mapBlockIndex.end()) return error("GetKernelStakeModifier() : block not indexed"); - const CBlockIndex* pindexFrom = mapBlockIndex[hashBlockFrom]; + const CBlockIndex* pindexFrom = mapItem->second; nStakeModifierHeight = pindexFrom->nHeight; nStakeModifierTime = pindexFrom->GetBlockTime(); int64_t nStakeModifierSelectionInterval = GetStakeModifierSelectionInterval(); diff --git a/src/main.cpp b/src/main.cpp index bc9b6a6fbf..ebcf3fd061 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3436,14 +3436,15 @@ bool ForceReorganizeToHash(uint256 NewHash) { CTxDB txdb; - if(!mapBlockIndex.count(NewHash)) + auto mapItem = mapBlockIndex.find(NewHash); + if(mapItem == mapBlockIndex.end()) return error("ForceReorganizeToHash: failed to find requested block in block index"); CBlockIndex* pindexCur = pindexBest; - CBlockIndex* pindexNew = mapBlockIndex[NewHash]; + CBlockIndex* pindexNew = mapItem->second; printf("\r\n** Force Reorganize **\r\n"); - printf(" Current best height %f hash %s\n",(double)pindexCur->nHeight,pindexCur->GetBlockHash().GetHex().c_str()); - printf(" Target height %f hash %s\n",(double)pindexNew->nHeight,pindexNew->GetBlockHash().GetHex().c_str()); + printf(" Current best height %i hash %s\n", pindexCur->nHeight,pindexCur->GetBlockHash().GetHex().c_str()); + printf(" Target height %i hash %s\n", pindexNew->nHeight,pindexNew->GetBlockHash().GetHex().c_str()); CBlock blockNew; if (!blockNew.ReadFromDisk(pindexNew)) @@ -5224,11 +5225,12 @@ StructCPID GetLifetimeCPID(const std::string& cpid, const std::string& sCalledFr if (fDebug10) printf("GetLifetimeCPID: trying %s\n",uHash.GetHex().c_str()); // Ensure that we have this block. - if (mapBlockIndex.count(uHash) == 0) + auto mapItem = mapBlockIndex.find(uHash); + if (mapItem == mapBlockIndex.end()) continue; // Ensure that the block is valid - CBlockIndex* pblockindex = mapBlockIndex[uHash]; + CBlockIndex* pblockindex = mapItem->second; if(pblockindex == NULL || pblockindex->IsInMainChain() == false || pblockindex->GetCPID() != cpid) @@ -8355,8 +8357,12 @@ CBlockIndex* GetHistoricalMagnitude(std::string cpid) if (!stCPID.BlockHash.empty()) { uint256 hash(stCPID.BlockHash); - if (mapBlockIndex.count(hash) == 0) return pindexGenesisBlock; - CBlockIndex* pblockindex = mapBlockIndex[hash]; + + auto mapItem = mapBlockIndex.find(hash); + if (mapItem == mapBlockIndex.end()) + return pindexGenesisBlock; + + CBlockIndex* pblockindex = mapItem->second; if(!pblockindex->pnext) printf("GetHistoricalMagnitude: WARNING index {%s %d} for cpid %s, " "has no next pointer (not n main chain)\n",pblockindex->GetBlockHash().GetHex().c_str(), diff --git a/src/wallet.cpp b/src/wallet.cpp index 926e6a4f60..aac1c108b2 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -463,7 +463,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) wtx.nTimeSmart = wtx.nTimeReceived; if (wtxIn.hashBlock != 0) { - if (mapBlockIndex.count(wtxIn.hashBlock)) + auto mapItem = mapBlockIndex.find(wtxIn.hashBlock); + if (mapItem != mapBlockIndex.end()) { unsigned int latestNow = wtx.nTimeReceived; unsigned int latestEntry = 0; @@ -497,7 +498,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) } } - unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime; + unsigned int& blocktime = mapItem->second->nTime; wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow)); } else From f6dc093596432717b01973f545fe432819699450 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Wed, 25 Oct 2017 21:17:45 +0200 Subject: [PATCH 094/166] Revert "Remove PoW check which cannot happen anymore." This reverts commit 1c92c2e9810933c9c1e1d751c60646a9866c2291. There isn't much of a gain to remove this check so until we are 100% sure that it's safe it'll stay. --- src/main.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index b71129b1da..e6f2db112b 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1790,6 +1790,21 @@ int64_t GetProofOfWorkReward(int64_t nFees, int64_t locktime, int64_t height) return nSubsidy + nFees; } + +int64_t GetProofOfWorkMaxReward(int64_t nFees, int64_t locktime, int64_t height) +{ + int64_t nSubsidy = (GetMaximumBoincSubsidy(locktime)+1) * COIN; + if (height==10) + { + //R.Halford: 10-11-2014: Gridcoin Foundation Block: + //Note: Gridcoin Classic emitted these coins. So we had to add them to block 10. The coins were burned then given back to the owners that mined them in classic (as research coins). + nSubsidy = nGenesisSupply * COIN; + } + + if (fTestNet) nSubsidy += 1000*COIN; + return nSubsidy + nFees; +} + //Survey Results: Start inflation rate: 9%, end=1%, 30 day steps, 9 steps, mag multiplier start: 2, mag end .3, 9 steps int64_t GetMaximumBoincSubsidy(int64_t nTime) { @@ -2948,6 +2963,16 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size()); } + if (IsProofOfWork() && pindex->nHeight > nGrandfather) + { + int64_t nReward = GetProofOfWorkMaxReward(nFees,nTime,pindex->nHeight); + // Check coinbase reward + if (vtx[0].GetValueOut() > nReward) + return DoS(50, error("ConnectBlock[] : coinbase reward exceeded (actual=%" PRId64 " vs calculated=%" PRId64 ")", + vtx[0].GetValueOut(), + nReward)); + } + MiningCPID bb = DeserializeBoincBlock(vtx[0].hashBoinc,nVersion); uint64_t nCoinAge = 0; From c931b5871de0b85ebac6a9b7bf74e0e29cfc3257 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 28 Oct 2017 07:03:21 +0200 Subject: [PATCH 095/166] Remove unused REORGANIZE_FAILED variable. --- src/main.cpp | 6 +----- src/main.h | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e6f2db112b..d468339ce6 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -143,7 +143,6 @@ CCriticalSection cs_main; extern std::string NodeAddress(CNode* pfrom); CTxMemPool mempool; -unsigned int REORGANIZE_FAILED = 0; unsigned int WHITELISTED_PROJECTS = 0; int64_t nLastPing = 0; int64_t nLastAskedForBlocks = 0; @@ -3572,13 +3571,11 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) InvalidChainFound(pindexNew); printf("\r\nReorg tally\r\n"); TallyNetworkAverages(); - REORGANIZE_FAILED++; return error("SetBestChain() : Reorganize failed"); } } - // Switch to new best branch - REORGANIZE_FAILED=0; + // Switch to new best branch // Connect further blocks for (auto &pindex : boost::adaptors::reverse(vpindexSecondary)) { @@ -3652,7 +3649,6 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) boost::replace_all(strCmd, "%s", hashBestChain.GetHex()); boost::thread t(runCommand, strCmd); // thread runs free } - REORGANIZE_FAILED=0; return true; } diff --git a/src/main.h b/src/main.h index 4e15280e10..9bde5aa5ef 100755 --- a/src/main.h +++ b/src/main.h @@ -27,7 +27,6 @@ class CNode; class CTxMemPool; static const int LAST_POW_BLOCK = 2050; -extern unsigned int REORGANIZE_FAILED; extern unsigned int WHITELISTED_PROJECTS; static const int CONSENSUS_LOOKBACK = 5; //Amount of blocks to go back from best block, to avoid counting forked blocks static const int BLOCK_GRANULARITY = 10; //Consensus block divisor From 826c8e578e400c6db74fc431f8175dddbd1e4173 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 29 Oct 2017 10:55:49 +0100 Subject: [PATCH 096/166] Fix build errors when using DEBUG_LOCKORDER define. --- src/sync.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sync.cpp b/src/sync.cpp index 4bec18cbdc..3b5dd48492 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -41,7 +41,7 @@ struct CLockLocation { std::string ToString() const { - return mutexName + " " + sourceFile + ":" + ToString(sourceLine) + (fTry ? " (TRY)" : ""); + return mutexName + " " + sourceFile + ":" + ::ToString(sourceLine) + (fTry ? " (TRY)" : ""); } bool fTry; @@ -82,7 +82,7 @@ static void potential_deadlock_detected(const std::pair& mismatch, if (i.first == mismatch.second) { printf(" (2)"); } - printf(" %s\n", i.second.ToString()); + printf(" %s\n", i.second.ToString().c_str()); } printf("Current lock order is:\n"); for (const std::pair & i : s1) { @@ -92,7 +92,7 @@ static void potential_deadlock_detected(const std::pair& mismatch, if (i.first == mismatch.second) { printf(" (2)"); } - printf(" %s\n", i.second.ToString()); + printf(" %s\n", i.second.ToString().c_str()); } assert(false); } From 0da4d513ef96f03c4d201b10c4457218d57fae4f Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 29 Oct 2017 11:29:35 +0100 Subject: [PATCH 097/166] Fix two lock order issues which are very likely to result in deadlocks. --- src/main.cpp | 297 ++++++++++++++++++++++++++------------------------- src/net.cpp | 17 +-- 2 files changed, 159 insertions(+), 155 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d468339ce6..17e790b3c6 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -6860,7 +6860,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // requires LOCK(cs_vRecvMsg) bool ProcessMessages(CNode* pfrom) -{ +{ + LOCK(cs_main); + + TRY_LOCK(pfrom->cs_vRecvMsg, lockRecv); + if (!lockRecv) + return true; + // // Message format // (4) message start @@ -6928,10 +6934,7 @@ bool ProcessMessages(CNode* pfrom) bool fRet = false; try { - { - LOCK(cs_main); - fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime); - } + fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime); if (fShutdown) break; } @@ -7632,184 +7635,192 @@ void TrackRequests(CNode* pfrom,std::string sRequestType) bool SendMessages(CNode* pto, bool fSendTrickle) { + // Treat lock failures as send successes in case the caller disconnects + // the node based on the return value. TRY_LOCK(cs_main, lockMain); - if (lockMain) { - // Don't send anything until we get their version message - if (pto->nVersion == 0) - return true; + if(!lockMain) + return true; - // - // Message: ping - // - bool pingSend = false; - if (pto->fPingQueued) - { - // RPC ping request by user - pingSend = true; + TRY_LOCK(pto->cs_vSend, lockSend); + if (!lockSend) + return true; + + // Don't send anything until we get their version message + if (pto->nVersion == 0) + return true; + + // + // Message: ping + // + bool pingSend = false; + if (pto->fPingQueued) + { + // RPC ping request by user + pingSend = true; + } + if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) + { + // Ping automatically sent as a latency probe & keepalive. + pingSend = true; + } + if (pingSend) + { + uint64_t nonce = 0; + while (nonce == 0) { + RAND_bytes((unsigned char*)&nonce, sizeof(nonce)); } - if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) + pto->fPingQueued = false; + pto->nPingUsecStart = GetTimeMicros(); + if (pto->nVersion > BIP0031_VERSION) { - // Ping automatically sent as a latency probe & keepalive. - pingSend = true; - } - if (pingSend) + pto->nPingNonceSent = nonce; + std::string acid = GetCommandNonce("ping"); + pto->PushMessage("ping", nonce, acid); + } else { - uint64_t nonce = 0; - while (nonce == 0) { - RAND_bytes((unsigned char*)&nonce, sizeof(nonce)); - } - pto->fPingQueued = false; - pto->nPingUsecStart = GetTimeMicros(); - if (pto->nVersion > BIP0031_VERSION) - { - pto->nPingNonceSent = nonce; - std::string acid = GetCommandNonce("ping"); - pto->PushMessage("ping", nonce, acid); - } else - { - // Peer is too old to support ping command with nonce, pong will never arrive. - pto->nPingNonceSent = 0; - pto->PushMessage("ping"); - } + // Peer is too old to support ping command with nonce, pong will never arrive. + pto->nPingNonceSent = 0; + pto->PushMessage("ping"); } + } - // Resend wallet transactions that haven't gotten in a block yet - ResendWalletTransactions(); + // Resend wallet transactions that haven't gotten in a block yet + ResendWalletTransactions(); - // Address refresh broadcast - static int64_t nLastRebroadcast; - if (!IsInitialBlockDownload() && ( GetAdjustedTime() - nLastRebroadcast > 24 * 60 * 60)) + // Address refresh broadcast + static int64_t nLastRebroadcast; + if (!IsInitialBlockDownload() && ( GetAdjustedTime() - nLastRebroadcast > 24 * 60 * 60)) + { { + LOCK(cs_vNodes); + for (auto const& pnode : vNodes) { - LOCK(cs_vNodes); - for (auto const& pnode : vNodes) - { - // Periodically clear setAddrKnown to allow refresh broadcasts - if (nLastRebroadcast) - pnode->setAddrKnown.clear(); + // Periodically clear setAddrKnown to allow refresh broadcasts + if (nLastRebroadcast) + pnode->setAddrKnown.clear(); - // Rebroadcast our address - if (!fNoListen) - { - CAddress addr = GetLocalAddress(&pnode->addr); - if (addr.IsRoutable()) - pnode->PushAddress(addr); - } + // Rebroadcast our address + if (!fNoListen) + { + CAddress addr = GetLocalAddress(&pnode->addr); + if (addr.IsRoutable()) + pnode->PushAddress(addr); } } - nLastRebroadcast = GetAdjustedTime(); } + nLastRebroadcast = GetAdjustedTime(); + } - // - // Message: addr - // - if (fSendTrickle) + // + // Message: addr + // + if (fSendTrickle) + { + vector vAddr; + vAddr.reserve(pto->vAddrToSend.size()); + for (auto const& addr : pto->vAddrToSend) { - vector vAddr; - vAddr.reserve(pto->vAddrToSend.size()); - for (auto const& addr : pto->vAddrToSend) + // returns true if wasn't already contained in the set + if (pto->setAddrKnown.insert(addr).second) { - // returns true if wasn't already contained in the set - if (pto->setAddrKnown.insert(addr).second) + vAddr.push_back(addr); + // receiver rejects addr messages larger than 1000 + if (vAddr.size() >= 1000) { - vAddr.push_back(addr); - // receiver rejects addr messages larger than 1000 - if (vAddr.size() >= 1000) - { - pto->PushMessage("gridaddr", vAddr); - vAddr.clear(); - } + pto->PushMessage("gridaddr", vAddr); + vAddr.clear(); } } - pto->vAddrToSend.clear(); - if (!vAddr.empty()) - pto->PushMessage("gridaddr", vAddr); } + pto->vAddrToSend.clear(); + if (!vAddr.empty()) + pto->PushMessage("gridaddr", vAddr); + } - // - // Message: inventory - // - vector vInv; - vector vInvWait; + // + // Message: inventory + // + vector vInv; + vector vInvWait; + { + LOCK(pto->cs_inventory); + vInv.reserve(pto->vInventoryToSend.size()); + vInvWait.reserve(pto->vInventoryToSend.size()); + for (auto const& inv : pto->vInventoryToSend) { - LOCK(pto->cs_inventory); - vInv.reserve(pto->vInventoryToSend.size()); - vInvWait.reserve(pto->vInventoryToSend.size()); - for (auto const& inv : pto->vInventoryToSend) - { - if (pto->setInventoryKnown.count(inv)) - continue; + if (pto->setInventoryKnown.count(inv)) + continue; - // trickle out tx inv to protect privacy - if (inv.type == MSG_TX && !fSendTrickle) + // trickle out tx inv to protect privacy + if (inv.type == MSG_TX && !fSendTrickle) + { + // 1/4 of tx invs blast to all immediately + static uint256 hashSalt; + if (hashSalt == 0) + hashSalt = GetRandHash(); + uint256 hashRand = inv.hash ^ hashSalt; + hashRand = Hash(BEGIN(hashRand), END(hashRand)); + bool fTrickleWait = ((hashRand & 3) != 0); + + // always trickle our own transactions + if (!fTrickleWait) { - // 1/4 of tx invs blast to all immediately - static uint256 hashSalt; - if (hashSalt == 0) - hashSalt = GetRandHash(); - uint256 hashRand = inv.hash ^ hashSalt; - hashRand = Hash(BEGIN(hashRand), END(hashRand)); - bool fTrickleWait = ((hashRand & 3) != 0); - - // always trickle our own transactions - if (!fTrickleWait) - { - CWalletTx wtx; - if (GetTransaction(inv.hash, wtx)) - if (wtx.fFromMe) - fTrickleWait = true; - } + CWalletTx wtx; + if (GetTransaction(inv.hash, wtx)) + if (wtx.fFromMe) + fTrickleWait = true; + } - if (fTrickleWait) - { - vInvWait.push_back(inv); - continue; - } + if (fTrickleWait) + { + vInvWait.push_back(inv); + continue; } + } - // returns true if wasn't already contained in the set - if (pto->setInventoryKnown.insert(inv).second) + // returns true if wasn't already contained in the set + if (pto->setInventoryKnown.insert(inv).second) + { + vInv.push_back(inv); + if (vInv.size() >= 1000) { - vInv.push_back(inv); - if (vInv.size() >= 1000) - { - pto->PushMessage("inv", vInv); - vInv.clear(); - } + pto->PushMessage("inv", vInv); + vInv.clear(); } } - pto->vInventoryToSend = vInvWait; } - if (!vInv.empty()) - pto->PushMessage("inv", vInv); + pto->vInventoryToSend = vInvWait; + } + if (!vInv.empty()) + pto->PushMessage("inv", vInv); - // - // Message: getdata - // - vector vGetData; - int64_t nNow = GetAdjustedTime() * 1000000; - CTxDB txdb("r"); - while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) + // + // Message: getdata + // + vector vGetData; + int64_t nNow = GetAdjustedTime() * 1000000; + CTxDB txdb("r"); + while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) + { + const CInv& inv = (*pto->mapAskFor.begin()).second; + if (!AlreadyHave(txdb, inv)) { - const CInv& inv = (*pto->mapAskFor.begin()).second; - if (!AlreadyHave(txdb, inv)) + if (fDebugNet) printf("sending getdata: %s\n", inv.ToString().c_str()); + vGetData.push_back(inv); + if (vGetData.size() >= 1000) { - if (fDebugNet) printf("sending getdata: %s\n", inv.ToString().c_str()); - vGetData.push_back(inv); - if (vGetData.size() >= 1000) - { - pto->PushMessage("getdata", vGetData); - vGetData.clear(); - } - mapAlreadyAskedFor[inv] = nNow; + pto->PushMessage("getdata", vGetData); + vGetData.clear(); } - pto->mapAskFor.erase(pto->mapAskFor.begin()); + mapAlreadyAskedFor[inv] = nNow; } - if (!vGetData.empty()) - pto->PushMessage("getdata", vGetData); + pto->mapAskFor.erase(pto->mapAskFor.begin()); } + if (!vGetData.empty()) + pto->PushMessage("getdata", vGetData); + return true; } diff --git a/src/net.cpp b/src/net.cpp index 9709bc77d2..7364f7252e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1982,26 +1982,19 @@ void ThreadMessageHandler2(void* parg) pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; for (auto const& pnode : vNodesCopy) { - if (pnode->fDisconnect) continue; + //11-25-2015 // Receive messages - { - TRY_LOCK(pnode->cs_vRecvMsg, lockRecv); - if (lockRecv) - if (!ProcessMessages(pnode)) - pnode->CloseSocketDisconnect(); - } + if (!ProcessMessages(pnode)) + pnode->CloseSocketDisconnect(); + if (fShutdown) return; // Send messages - { - TRY_LOCK(pnode->cs_vSend, lockSend); - if (lockSend) - SendMessages(pnode, pnode == pnodeTrickle); - } + SendMessages(pnode, pnode == pnodeTrickle); if (fShutdown) return; } From e7066077c918b51a4c97ad731daadc0355ff5819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Wed, 25 Oct 2017 22:41:53 +0200 Subject: [PATCH 098/166] Attempt for transition between the new and old tally. * re-introduced the old tally functions with `*_retired` suffix * renamed new tally implementation to `*_v9 suffix` * reverted to the old grandfather configuration * avoid "retallying" and "doublecheck" in `CheckProofOfResearch` (one instance of "doublecheck" still left in `ConnectBlock`) * added transition After 120 v9 blocks, or 3 hours after switch to v9, old tally mechanism will be disabled and the new implementation engaged. This 3 hour delay was chosen to ensure the network and tally are stable after switching to v9. This also ensures that most of outdated nodes will be already banned. --- src/init.cpp | 8 +- src/main.cpp | 268 ++++++++++++++++++++++++++++++++++++++---- src/main.h | 5 + src/net.cpp | 89 +++++++++++++- src/rpcblockchain.cpp | 9 ++ 5 files changed, 355 insertions(+), 24 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 922ce3a154..906eb1594a 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -24,7 +24,8 @@ bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); StructCPID GetStructCPID(); bool ComputeNeuralNetworkSupermajorityHashes(); -void TallyNetworkAverages(); +void BusyWaitForTally_retired(); +void TallyNetworkAverages_v9(); extern void ThreadAppInit2(void* parg); void LoadCPIDsInBackground(); @@ -994,11 +995,14 @@ bool AppInit2(ThreadHandlerPtr threads) uiInterface.InitMessage(_("Loading Network Averages...")); if (fDebug3) printf("Loading network averages"); - TallyNetworkAverages(); + + TallyNetworkAverages_v9(); if (!threads->createThread(StartNode, NULL, "Start Thread")) InitError(_("Error: could not start node")); + BusyWaitForTally_retired(); + if (fServer) threads->createThread(ThreadRPCServer, NULL, "RPC Server Thread"); diff --git a/src/main.cpp b/src/main.cpp index d468339ce6..66f9cd2c15 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,7 +51,8 @@ bool RequestSupermajorityNeuralData(); extern bool AskForOutstandingBlocks(uint256 hashStart); extern bool CleanChain(); extern void ResetTimerMain(std::string timer_name); -extern bool TallyResearchAverages(); +extern bool TallyResearchAverages_retired(bool Forcefully); +extern bool TallyNetworkAverages_v9(); extern void IncrementCurrentNeuralNetworkSupermajority(std::string NeuralHash, std::string GRCAddress, double distance); bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature); int DetermineCPIDType(std::string cpid); @@ -62,6 +63,8 @@ extern double ExtractMagnitudeFromExplainMagnitude(); extern void GridcoinServices(); extern double SnapToGrid(double d); extern bool StrLessThanReferenceHash(std::string rh); +void BusyWaitForTally_retired(); +extern bool TallyNetworkAverages_retired(bool Forcefully); extern bool TallyNetworkAverages(); extern bool IsContract(CBlockIndex* pIndex); std::string ExtractValue(std::string data, std::string delimiter, int pos); @@ -252,11 +255,14 @@ extern std::string RetrieveMd5(std::string s1); extern std::string aes_complex_hash(uint256 scrypt_hash); bool bNetAveragesLoaded = false; +bool bTallyStarted_retired = false; bool bForceUpdate = false; bool bCheckedForUpgrade = false; bool bCheckedForUpgradeLive = false; bool bGlobalcomInitialized = false; bool bStakeMinerOutOfSyncWithNetwork = false; +volatile bool bDoTally_retired = false; +volatile bool bTallyFinished_retired = false; bool bGridcoinGUILoaded = false; extern double LederstrumpfMagnitude2(double Magnitude, int64_t locktime); @@ -307,7 +313,7 @@ std::string msNeuralResponse; std::string msHDDSerial; //When syncing, we grandfather block rejection rules up to this block, as rules became stricter over time and fields changed -int nGrandfather = 1035000; +int nGrandfather = 1034700; int nNewIndex = 271625; int nNewIndex2 = 364500; @@ -2172,14 +2178,27 @@ bool CheckProofOfResearch( int64_t nCalculatedResearch = GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 1, block.nTime, pindexBest, "checkblock_researcher", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); - // TODO: Remove this tally? - if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) + if(!IsV9Enabled_Tally(pindexPrev->nHeight)) { - if (fDebug3) printf("CheckProofOfResearch: Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", - bb.InterestSubsidy, bb.ResearchSubsidy, CoinToDouble(nCalculatedResearch), OUT_POR, OUT_INTEREST, bb.cpid.c_str()); + if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) + { + if (fDebug) printf("CheckProofOfResearch: Researchers Reward Pays too much : Retallying : " + "claimedand %f vs calculated StakeReward %f for CPID %s\n", + bb.ResearchSubsidy, OUT_POR, bb.cpid.c_str() ); - return block.DoS(10,error("CheckProofOfResearch: Researchers Reward Pays too much : Interest %f and Research %f and StakeReward %f, OUT_POR %f, with Out_Interest %f for CPID %s ", - bb.InterestSubsidy, bb.ResearchSubsidy,CoinToDouble(nCalculatedResearch), OUT_POR, OUT_INTEREST, bb.cpid.c_str())); + BusyWaitForTally_retired(); + StructCPID st1 = GetLifetimeCPID(bb.cpid,"CheckProofOfResearch()"); + nCalculatedResearch = GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 2, block.nTime, + pindexBest, "checkblock_researcher_doublecheck", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); + } + } + (void)nCalculatedResearch; + + if (bb.ResearchSubsidy > ((OUT_POR*1.25)+1)) + { + return block.DoS(10,error("CheckProofOfResearch: Researchers Reward Pays too much : " + "claimed %f vs calculated %f for CPID %s", + bb.ResearchSubsidy, OUT_POR, bb.cpid.c_str() )); } return true; @@ -2983,7 +3002,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo if (IsProofOfStake() && pindex->nHeight > nGrandfather) { - // ppcoin: coin stake tx earns reward instead of paying fee + // ppcoin: coin stake tx earns reward instead of paying fee if (!vtx[1].GetCoinAge(txdb, nCoinAge)) return error("ConnectBlock[] : %s unable to get coin age for coinstake", vtx[1].GetHash().ToString().substr(0,10).c_str()); @@ -3129,6 +3148,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo { if (bb.ResearchSubsidy > (GetOwedAmount(bb.cpid)+1)) { + bDoTally_retired=true; if (bb.ResearchSubsidy > (GetOwedAmount(bb.cpid)+1)) { StructCPID strUntrustedHost = GetInitializedStructCPID2(bb.cpid,mvMagnitudes); @@ -3220,6 +3240,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo //If we are out of sync, and research age is enabled, and the superblock is valid, load it now, so we can continue checking blocks accurately + // I would suggest to NOT bother with superblock at all here. It will be loaded in tally. if ((OutOfSyncByAge() || fColdBoot || fReorganizing) && IsResearchAgeEnabled(pindex->nHeight) && pindex->nHeight > nGrandfather) { if (bb.superblock.length() > 20) @@ -3229,6 +3250,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo { LoadSuperblock(superblock,pindex->nTime,pindex->nHeight); if (fDebug3) printf("ConnectBlock(): Superblock Loaded %d \r\n", pindex->nHeight); + if (!fColdBoot) + { + bDoTally_retired = true; + } } else { @@ -3281,9 +3306,17 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo LoadAdminMessages(false,errors1); } + // Slow down Retallying when in RA mode so we minimize disruption of the network + if ( (pindex->nHeight % 60 == 0) && IsResearchAgeEnabled(pindex->nHeight) && BlockNeedsChecked(pindex->nTime)) + { + if (fDebug3) printf("\r\n*BusyWaitForTally_retired*\r\n"); + BusyWaitForTally_retired(); + } + if (IsResearchAgeEnabled(pindex->nHeight) && !OutOfSyncByAge()) { fColdBoot = false; + bDoTally_retired=true; } if (fJustCheck) @@ -3570,7 +3603,8 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) txdb.TxnAbort(); InvalidChainFound(pindexNew); printf("\r\nReorg tally\r\n"); - TallyNetworkAverages(); + BusyWaitForTally_retired(); + TallyNetworkAverages_v9(); return error("SetBestChain() : Reorganize failed"); } } @@ -4244,6 +4278,11 @@ void GridcoinServices() printf("Daily backup results: Wallet -> %s Config -> %s\r\n", (bWalletBackupResults ? "true" : "false"), (bConfigBackupResults ? "true" : "false")); } + if (TimerMain("ResetVars",30)) + { + bTallyStarted_retired = false; + } + if (false && TimerMain("FixSpentCoins",60)) { int nMismatchSpent; @@ -4279,16 +4318,62 @@ void GridcoinServices() } } - // Update quorum data. - if ((nBestHeight % 3) == 0) + if(IsV9Enabled_Tally(nBestHeight)) { - ComputeNeuralNetworkSupermajorityHashes(); - UpdateNeuralNetworkQuorumData(); + // Update quorum data. + if ((nBestHeight % 3) == 0) + { + ComputeNeuralNetworkSupermajorityHashes(); + UpdateNeuralNetworkQuorumData(); + } + + // Tally research averages. + if ((nBestHeight % TALLY_GRANULARITY) == 0) + TallyNetworkAverages_v9(); } + else + { + int64_t superblock_age = GetAdjustedTime() - mvApplicationCacheTimestamp["superblock;magnitudes"]; + bool bNeedSuperblock = (superblock_age > (GetSuperblockAgeSpacing(nBestHeight))); + if ( nBestHeight % 3 == 0 && NeedASuperblock() ) bNeedSuperblock=true; + + if (fDebug10) + { + printf (" MRSA %" PRId64 ", BH %d", superblock_age, nBestHeight); + } + + if (bNeedSuperblock) + { + if ((nBestHeight % 3) == 0) + { + if (fDebug10) printf("#CNNSH# "); + ComputeNeuralNetworkSupermajorityHashes(); + UpdateNeuralNetworkQuorumData(); + } + if ((nBestHeight % 20) == 0) + { + if (fDebug10) printf("#TIB# "); + bDoTally_retired = true; + } + } + else + { + // When superblock is not old, Tally every N mins: + int nTallyGranularity = fTestNet ? 60 : 20; + if ((nBestHeight % nTallyGranularity) == 0) + { + if (fDebug3) printf("TIB1 "); + bDoTally_retired = true; + if (fDebug3) printf("CNNSH2 "); + ComputeNeuralNetworkSupermajorityHashes(); + } - // Tally research averages. - if ((nBestHeight % TALLY_GRANULARITY) == 0) - TallyNetworkAverages(); + if ((nBestHeight % 5)==0) + { + UpdateNeuralNetworkQuorumData(); + } + } + } // Every N blocks as a Synchronized TEAM: if ((nBestHeight % 30) == 0) @@ -5424,8 +5509,146 @@ bool ComputeNeuralNetworkSupermajorityHashes() } -bool TallyResearchAverages() +bool TallyResearchAverages_retired(bool Forcefully) +{ + if(IsV9Enabled_Tally(nBestHeight)) + return error("TallyResearchAverages_retired: called while V9 tally enabled\n"); + + //Iterate throught last 14 days, tally network averages + if (nBestHeight < 15) + { + bNetAveragesLoaded = true; + return true; + } + + //8-27-2016 + int64_t nStart = GetTimeMillis(); + + if (fDebug) printf("Tallying Research Averages (begin) "); + bNetAveragesLoaded = false; + bool superblockloaded = false; + double NetworkPayments = 0; + double NetworkInterest = 0; + + //Consensus Start/End block: + int nMaxDepth = (nBestHeight-CONSENSUS_LOOKBACK) - ( (nBestHeight-CONSENSUS_LOOKBACK) % BLOCK_GRANULARITY); + int nLookback = BLOCKS_PER_DAY * 14; //Daily block count * Lookback in days + int nMinDepth = (nMaxDepth - nLookback) - ( (nMaxDepth-nLookback) % BLOCK_GRANULARITY); + if (fDebug3) printf("START BLOCK %f, END BLOCK %f ",(double)nMaxDepth,(double)nMinDepth); + if (nMinDepth < 2) nMinDepth = 2; + mvMagnitudesCopy.clear(); + int iRow = 0; + //CBlock block; + CBlockIndex* pblockindex = pindexBest; + if (!pblockindex) + { + bTallyStarted_retired = false; + bNetAveragesLoaded = true; + return true; + } + while (pblockindex->nHeight > nMaxDepth) + { + if (!pblockindex || !pblockindex->pprev || pblockindex == pindexGenesisBlock) return false; + pblockindex = pblockindex->pprev; + } + + if (fDebug3) printf("Max block %f, seektime %f",(double)pblockindex->nHeight,(double)GetTimeMillis()-nStart); + nStart=GetTimeMillis(); + + + // Headless critical section () + try + { + while (pblockindex->nHeight > nMinDepth) + { + if (!pblockindex || !pblockindex->pprev) return false; + pblockindex = pblockindex->pprev; + if (pblockindex == pindexGenesisBlock) return false; + if (!pblockindex->IsInMainChain()) continue; + NetworkPayments += pblockindex->nResearchSubsidy; + NetworkInterest += pblockindex->nInterestSubsidy; + AddResearchMagnitude(pblockindex); + + iRow++; + if (IsSuperBlock(pblockindex) && !superblockloaded) + { + MiningCPID bb = GetBoincBlockByIndex(pblockindex); + if (bb.superblock.length() > 20) + { + std::string superblock = UnpackBinarySuperblock(bb.superblock); + if (VerifySuperblock(superblock, pblockindex)) + { + LoadSuperblock(superblock,pblockindex->nTime,pblockindex->nHeight); + superblockloaded=true; + if (fDebug) + printf(" Superblock Loaded %i", pblockindex->nHeight); + } + } + } + + } + // End of critical section + if (fDebug3) printf("TNA loaded in %" PRId64, GetTimeMillis()-nStart); + nStart=GetTimeMillis(); + + + if (pblockindex) + { + if (fDebug3) + printf("Min block %i, Rows %i", pblockindex->nHeight, iRow); + + StructCPID network = GetInitializedStructCPID2("NETWORK",mvNetworkCopy); + network.projectname="NETWORK"; + network.payments = NetworkPayments; + network.InterestSubsidy = NetworkInterest; + mvNetworkCopy["NETWORK"] = network; + if(fDebug3) printf(" TMIS1 "); + TallyMagnitudesInSuperblock(); + } + // 11-19-2015 Copy dictionaries to live RAM + mvDPOR = mvDPORCopy; + mvMagnitudes = mvMagnitudesCopy; + mvNetwork = mvNetworkCopy; + bTallyStarted_retired = false; + bNetAveragesLoaded = true; + return true; + } + catch (bad_alloc ba) + { + printf("Bad Alloc while tallying network averages. [1]\r\n"); + bNetAveragesLoaded=true; + } + catch(...) + { + printf("Error while tallying network averages. [1]\r\n"); + bNetAveragesLoaded=true; + } + + if (fDebug3) printf("NA loaded in %f",(double)GetTimeMillis()-nStart); + + bNetAveragesLoaded=true; + return false; +} + + + +bool TallyNetworkAverages_retired(bool Forcefully) { + if (IsResearchAgeEnabled(pindexBest->nHeight) && !IsV9Enabled_Tally(pindexBest->nHeight)) + { + return TallyResearchAverages_retired(Forcefully); + } + + return false; +} + + + +bool TallyResearchAverages_v9() +{ + if(!IsV9Enabled_Tally(nBestHeight)) + return error("TallyResearchAverages_v9: called while V9 tally disabled\n"); + //Iterate throught last 14 days, tally network averages if (nBestHeight < 15) { @@ -5545,17 +5768,20 @@ bool TallyResearchAverages() -bool TallyNetworkAverages() +bool TallyNetworkAverages_v9() { - if (IsResearchAgeEnabled(pindexBest->nHeight)) + if (IsResearchAgeEnabled(pindexBest->nHeight) && IsV9Enabled_Tally(pindexBest->nHeight)) { - return TallyResearchAverages(); + return TallyResearchAverages_v9(); } return false; } + + + void PrintBlockTree() { AssertLockHeld(cs_main); diff --git a/src/main.h b/src/main.h index 9bde5aa5ef..fd517eab7c 100755 --- a/src/main.h +++ b/src/main.h @@ -113,6 +113,11 @@ inline bool AreBinarySuperblocksEnabled(int nHeight) return (fTestNet ? nHeight > 10000 : nHeight > 725000); } +inline bool IsV9Enabled_Tally(int nHeight) +{ + // 3 hours after v9 + return IsV9Enabled(nHeight-120); +} inline int64_t PastDrift(int64_t nTime, int nHeight) { return IsProtocolV2(nHeight) ? nTime - 20 * 60 : nTime - 20 * 60; } inline int64_t FutureDrift(int64_t nTime, int nHeight) { return IsProtocolV2(nHeight) ? nTime + 20 * 60 : nTime + 20 * 60; } diff --git a/src/net.cpp b/src/net.cpp index 9709bc77d2..cf89be3674 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1571,6 +1571,89 @@ void DumpAddresses() } +void DoTallyResearchAverages_retired(void* parg); +bool TallyNetworkAverages_retired(bool); +extern volatile bool bTallyFinished_retired; +extern volatile bool bDoTally_retired; + +void ThreadTallyResearchAverages_retired(void* parg) +{ + // Make this thread recognisable + RenameThread("grc-tallyresearchaverages"); + +begin: + try + { + DoTallyResearchAverages_retired(parg); + } + catch (std::exception& e) + { + PrintException(&e, "ThreadTallyNetworkAverages_retired()"); + } + catch(boost::thread_interrupted&) + { + printf("ThreadTallyResearchAverages_retired exited (interrupt)\r\n"); + return; + } + catch(...) + { + printf("Error in ThreadTallyResearchAverages_retired... Recovering \r\n"); + } + MilliSleep(10000); + if (!fShutdown) printf("Thread TallyReasearchAverages_retired exited, Restarting.. \r\n"); + if (!fShutdown) goto begin; + printf("ThreadTallyResearchAverages_retired exited \r\n"); +} + + +void BusyWaitForTally_retired() +{ + if (fDebug10) printf("\r\n ** Busy Wait for Tally_retired ** \r\n"); + bTallyFinished_retired=false; + bDoTally_retired=true; + int iTimeout = 0; + + int64_t deadline = GetAdjustedTime() + 15000; + while(!bTallyFinished_retired) + { + MilliSleep(10); + if(GetAdjustedTime() >= deadline) + break; + iTimeout+=1; + } +} + + +void DoTallyResearchAverages_retired(void* parg) +{ + printf("\r\nStarting dedicated Tally_retired thread...\r\n"); + + while (!fShutdown) + { + MilliSleep(100); + if (bDoTally_retired) + { + bTallyFinished_retired = false; + bDoTally_retired=false; + printf("\r\n[DoTallyRA_START_retired] "); + try + { + TallyNetworkAverages_retired(false); + } + catch (std::exception& e) + { + PrintException(&e, "ThreadTallyNetworkAverages_retired()"); + } + catch(...) + { + printf("\r\nError occurred in DoTallyResearchAverages_retired...Recovering\r\n"); + } + printf(" [DoTallyRA_END_retired] \r\n"); + bTallyFinished_retired = true; + } + } +} + void ThreadDumpAddress2(void* parg) { while (!fShutdown) @@ -2240,7 +2323,11 @@ void StartNode(void* parg) // Dump network addresses if (!netThreads->createThread(ThreadDumpAddress,NULL,"ThreadDumpAddress")) printf("Error: createThread(ThreadDumpAddress) failed\r\n"); - + + // Tally network averages + if (!NewThread(ThreadTallyResearchAverages_retired, NULL)) + printf("Error; NewThread(ThreadTally_retired) failed\n"); + // Mine proof-of-stake blocks in the background if (!GetBoolArg("-staking", true)) printf("Staking disabled\r\n"); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 2d9e559e0e..933528b579 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -42,6 +42,8 @@ extern Array MagnitudeReport(std::string cpid); std::string ConvertBinToHex(std::string a); std::string ConvertHexToBin(std::string a); extern std::vector readFileToVector(std::string filename); +bool bNetAveragesLoaded_retired; +bool TallyResearchAverages_retired(bool); int RestartClient(); extern std::string SignBlockWithCPID(std::string sCPID, std::string sBlockHash); std::string BurnCoinsWithNewContract(bool bAdd, std::string sType, std::string sPrimaryKey, std::string sValue, int64_t MinimumBalance, double dFees, std::string strPublicKey, std::string sBurnAddress); @@ -2042,6 +2044,13 @@ Value execute(const Array& params, bool fHelp) entry.push_back(Pair("Requested a quorum - waiting for resolution.",1)); results.push_back(entry); } + else if (sItem == "tally") + { + bNetAveragesLoaded_retired = false; + TallyResearchAverages_retired(true); + entry.push_back(Pair("Tally Network Averages",1)); + results.push_back(entry); + } else if (sItem == "encrypt") { //Encrypt a phrase From 3221fd6efca62909896cb518bad0cf1e8c1df651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Wed, 25 Oct 2017 23:43:34 +0200 Subject: [PATCH 099/166] Added trace messages to various tally releated places. --- src/main.cpp | 26 ++++++++++++++++++++------ src/net.cpp | 7 +++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 66f9cd2c15..e16f992a4b 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3249,7 +3249,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo if (VerifySuperblock(superblock, pindex)) { LoadSuperblock(superblock,pindex->nTime,pindex->nHeight); - if (fDebug3) printf("ConnectBlock(): Superblock Loaded %d \r\n", pindex->nHeight); + if (fDebug) + printf("ConnectBlock(): Superblock Loaded %d\n", pindex->nHeight); if (!fColdBoot) { bDoTally_retired = true; @@ -4323,13 +4324,18 @@ void GridcoinServices() // Update quorum data. if ((nBestHeight % 3) == 0) { + if(fDebug) printf("SVC: Updating Neural Quorum (v9 %%3) height %d\n",nBestHeight); + if(fDebug) printf("SVC: Updating Neural Supermajority (v9 %%3) height %d\n",nBestHeight); ComputeNeuralNetworkSupermajorityHashes(); UpdateNeuralNetworkQuorumData(); } // Tally research averages. if ((nBestHeight % TALLY_GRANULARITY) == 0) + { + if(fDebug) printf("SVC: TallyNetworkAverages (v9 %%%d) height %d\n",TALLY_GRANULARITY,nBestHeight); TallyNetworkAverages_v9(); + } } else { @@ -4346,12 +4352,15 @@ void GridcoinServices() { if ((nBestHeight % 3) == 0) { + if(fDebug) printf("SVC: Updating Neural Quorum (v3 A) height %d\n",nBestHeight); + if(fDebug) printf("SVC: Updating Neural Supermajority (v3 A) height %d\n",nBestHeight); if (fDebug10) printf("#CNNSH# "); ComputeNeuralNetworkSupermajorityHashes(); UpdateNeuralNetworkQuorumData(); } if ((nBestHeight % 20) == 0) { + if(fDebug) printf("SVC: set off Tally (v3 B) height %d\n",nBestHeight); if (fDebug10) printf("#TIB# "); bDoTally_retired = true; } @@ -4362,14 +4371,17 @@ void GridcoinServices() int nTallyGranularity = fTestNet ? 60 : 20; if ((nBestHeight % nTallyGranularity) == 0) { + if(fDebug) printf("SVC: set off Tally (v3 C) height %d\n",nBestHeight); if (fDebug3) printf("TIB1 "); bDoTally_retired = true; if (fDebug3) printf("CNNSH2 "); + if(fDebug) printf("SVC: Updating Neural Supermajority (v3 D) height %d\n",nBestHeight); ComputeNeuralNetworkSupermajorityHashes(); } if ((nBestHeight % 5)==0) { + if(fDebug) printf("SVC: Updating Neural Quorum (v3 E) height %d\n",nBestHeight); UpdateNeuralNetworkQuorumData(); } } @@ -5536,6 +5548,7 @@ bool TallyResearchAverages_retired(bool Forcefully) int nMinDepth = (nMaxDepth - nLookback) - ( (nMaxDepth-nLookback) % BLOCK_GRANULARITY); if (fDebug3) printf("START BLOCK %f, END BLOCK %f ",(double)nMaxDepth,(double)nMinDepth); if (nMinDepth < 2) nMinDepth = 2; + if(fDebug) printf("TallyResearchAverages_retired: start %d end %d\n",nMaxDepth,nMinDepth); mvMagnitudesCopy.clear(); int iRow = 0; //CBlock block; @@ -5581,7 +5594,7 @@ bool TallyResearchAverages_retired(bool Forcefully) LoadSuperblock(superblock,pblockindex->nTime,pblockindex->nHeight); superblockloaded=true; if (fDebug) - printf(" Superblock Loaded %i", pblockindex->nHeight); + printf("TallyResearchAverages_retired: Superblock Loaded {%s %i}\n", pblockindex->GetBlockHash().GetHex().c_str(),pblockindex->nHeight); } } } @@ -5664,7 +5677,7 @@ bool TallyResearchAverages_v9() bool superblockloaded = false; double NetworkPayments = 0; double NetworkInterest = 0; - + //Consensus Start/End block: int nMaxConensusDepth = nBestHeight - CONSENSUS_LOOKBACK; int nMaxDepth = nMaxConensusDepth - (nMaxConensusDepth % TALLY_GRANULARITY); @@ -5672,8 +5685,9 @@ bool TallyResearchAverages_v9() int nMinDepth = nMaxDepth - nLookback; if (nMinDepth < 2) nMinDepth = 2; - - if (fDebug3) printf("START BLOCK %i, END BLOCK %i", nMaxDepth, nMinDepth); + + if(fDebug) printf("TallyResearchAverages: start %d end %d\n",nMaxDepth,nMinDepth); + mvMagnitudesCopy.clear(); int iRow = 0; @@ -5718,7 +5732,7 @@ bool TallyResearchAverages_v9() LoadSuperblock(superblock,pblockindex->nTime,pblockindex->nHeight); superblockloaded=true; if (fDebug) - printf(" Superblock Loaded %i", pblockindex->nHeight); + printf("TallyResearchAverages_v9: Superblock Loaded {%s %i}\n", pblockindex->GetBlockHash().GetHex().c_str(),pblockindex->nHeight); } } } diff --git a/src/net.cpp b/src/net.cpp index cf89be3674..fb8dc3c2a0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1608,6 +1608,13 @@ void ThreadTallyResearchAverages_retired(void* parg) void BusyWaitForTally_retired() { + if(IsV9Enabled_Tally(nBestHeight)) + { + if(fDebug10) + printf("BusyWaitForTally_retired: skipped (v9 enabled)\n"); + return; + } + if (fDebug10) printf("\r\n ** Busy Wait for Tally_retired ** \r\n"); bTallyFinished_retired=false; bDoTally_retired=true; From 406518f30bc1cefd89fcd9de6b10e7d499257550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 29 Oct 2017 20:54:29 +0100 Subject: [PATCH 100/166] Change RoundFromString to use lexical cast again. This corrects regression from f91355b832fba6defd71e5c65a2e439182acb7d2, but is worse performance-vise. --- src/util.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/util.cpp b/src/util.cpp index 7bfd820b1e..e94c901b01 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -13,6 +13,7 @@ #include #include //For day of year #include +#include // Work around clang compilation problem in Boost 1.46: // /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup @@ -1464,7 +1465,8 @@ std::string RoundToString(double d, int place) double RoundFromString(const std::string& s, int place) { - return Round(atof(s.c_str()), place); + double num = boost::lexical_cast(s); + return Round(num, place); } bool Contains(const std::string& data, const std::string& instring) From 4d33b0e4a2a7eb9056ce0085364442d0ed83ae16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Mon, 30 Oct 2017 16:54:06 +0100 Subject: [PATCH 101/166] Prevent superblock when not needed and always check it. --- src/main.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e16f992a4b..f8091b93de 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3180,7 +3180,12 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo if (bb.superblock.length() > 20) { - if (pindex->nHeight > nGrandfather && !fReorganizing) + // Prevent duplicate superblocks + if(nVersion >= 9 && !NeedASuperblock()) + return error(("ConnectBlock: SuperBlock rcvd, but not Needed (too early)")); + + // Always perform SB checks in v9 + if ((pindex->nHeight > nGrandfather && !fReorganizing) || pindex->nVersion >= 9 ) { // 12-20-2015 : Add support for Binary Superblocks std::string superblock = UnpackBinarySuperblock(bb.superblock); @@ -3238,7 +3243,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo } } - + if(nVersion<9) + { //If we are out of sync, and research age is enabled, and the superblock is valid, load it now, so we can continue checking blocks accurately // I would suggest to NOT bother with superblock at all here. It will be loaded in tally. if ((OutOfSyncByAge() || fColdBoot || fReorganizing) && IsResearchAgeEnabled(pindex->nHeight) && pindex->nHeight > nGrandfather) @@ -3262,12 +3268,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo } } } - - - - /* - -- Normal Superblocks are loaded 15 blocks later - */ + /* + -- Normal Superblocks are loaded during Tally + */ + } } // End of Network Consensus From 6c56c4b33866a3f1b888ad0be131306feba4ad15 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 3 Nov 2017 07:17:57 +0100 Subject: [PATCH 102/166] Remove delay when exiting tally thread. --- src/net.cpp | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index fb8dc3c2a0..4f22c53f83 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1580,28 +1580,7 @@ void ThreadTallyResearchAverages_retired(void* parg) { // Make this thread recognisable RenameThread("grc-tallyresearchaverages"); - -begin: - try - { - DoTallyResearchAverages_retired(parg); - } - catch (std::exception& e) - { - PrintException(&e, "ThreadTallyNetworkAverages_retired()"); - } - catch(boost::thread_interrupted&) - { - printf("ThreadTallyResearchAverages_retired exited (interrupt)\r\n"); - return; - } - catch(...) - { - printf("Error in ThreadTallyResearchAverages_retired... Recovering \r\n"); - } - MilliSleep(10000); - if (!fShutdown) printf("Thread TallyReasearchAverages_retired exited, Restarting.. \r\n"); - if (!fShutdown) goto begin; + DoTallyResearchAverages_retired(parg); printf("ThreadTallyResearchAverages_retired exited \r\n"); } From 973e453b2d31152a808283a2a43f0c91b9308c28 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 3 Nov 2017 07:18:38 +0100 Subject: [PATCH 103/166] Add the tally rate limit back to match old implementation. --- src/main.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index f8091b93de..085473d78a 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5537,8 +5537,17 @@ bool TallyResearchAverages_retired(bool Forcefully) return true; } + static int64_t lastTallied = 0; + int timespan = fTestNet ? 2 : 6; + if (IsLockTimeWithinMinutes(lastTallied,timespan)) + { + bNetAveragesLoaded = true; + return true; + } + //8-27-2016 int64_t nStart = GetTimeMillis(); + lastTallied = GetAdjustedTime(); if (fDebug) printf("Tallying Research Averages (begin) "); bNetAveragesLoaded = false; @@ -5634,11 +5643,13 @@ bool TallyResearchAverages_retired(bool Forcefully) { printf("Bad Alloc while tallying network averages. [1]\r\n"); bNetAveragesLoaded=true; + lastTallied = 0; } catch(...) { printf("Error while tallying network averages. [1]\r\n"); bNetAveragesLoaded=true; + lastTallied = 0; } if (fDebug3) printf("NA loaded in %f",(double)GetTimeMillis()-nStart); From 988b08cb4b5d8e50163a7675d814bcf7b5d0fc04 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 3 Nov 2017 07:43:02 +0100 Subject: [PATCH 104/166] Remove 14 day limit when scanning for superblock in v9 tally. --- src/main.cpp | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 085473d78a..2a583275da 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5689,7 +5689,6 @@ bool TallyResearchAverages_v9() if (fDebug) printf("Tallying Research Averages (begin) "); bNetAveragesLoaded = false; - bool superblockloaded = false; double NetworkPayments = 0; double NetworkInterest = 0; @@ -5704,23 +5703,44 @@ bool TallyResearchAverages_v9() if(fDebug) printf("TallyResearchAverages: start %d end %d\n",nMaxDepth,nMinDepth); mvMagnitudesCopy.clear(); - int iRow = 0; - CBlockIndex* pblockindex = pindexBest; if (!pblockindex) { bNetAveragesLoaded = true; return true; } + + // Seek to head of tally window. while (pblockindex->nHeight > nMaxDepth) { if (!pblockindex || !pblockindex->pprev || pblockindex == pindexGenesisBlock) return false; pblockindex = pblockindex->pprev; } - if (fDebug3) printf("Max block %f, seektime %f",(double)pblockindex->nHeight,(double)GetTimeMillis()-nStart); + if (fDebug3) printf("Max block %i, seektime %" PRId64, pblockindex->nHeight, GetTimeMillis()-nStart); nStart=GetTimeMillis(); + // Load newest superblock in tally window + for(CBlockIndex* sbIndex = pblockindex; + sbIndex != NULL; + sbIndex = sbIndex->pprev) + { + if(!IsSuperBlock(sbIndex)) + continue; + + MiningCPID bb = GetBoincBlockByIndex(sbIndex); + if(bb.superblock.length() <= 20) + continue; + + const std::string& superblock = UnpackBinarySuperblock(bb.superblock); + if(!VerifySuperblock(superblock, sbIndex)) + continue; + + LoadSuperblock(superblock, sbIndex->nTime, sbIndex->nHeight); + if (fDebug) + printf("TallyResearchAverages_v9: Superblock Loaded {%s %i}\n", sbIndex->GetBlockHash().GetHex().c_str(), sbIndex->nHeight); + break; + } // Headless critical section () try @@ -5734,24 +5754,6 @@ bool TallyResearchAverages_v9() NetworkPayments += pblockindex->nResearchSubsidy; NetworkInterest += pblockindex->nInterestSubsidy; AddResearchMagnitude(pblockindex); - - iRow++; - if (IsSuperBlock(pblockindex) && !superblockloaded) - { - MiningCPID bb = GetBoincBlockByIndex(pblockindex); - if (bb.superblock.length() > 20) - { - std::string superblock = UnpackBinarySuperblock(bb.superblock); - if (VerifySuperblock(superblock, pblockindex)) - { - LoadSuperblock(superblock,pblockindex->nTime,pblockindex->nHeight); - superblockloaded=true; - if (fDebug) - printf("TallyResearchAverages_v9: Superblock Loaded {%s %i}\n", pblockindex->GetBlockHash().GetHex().c_str(),pblockindex->nHeight); - } - } - } - } // End of critical section if (fDebug3) printf("TNA loaded in %" PRId64, GetTimeMillis()-nStart); @@ -5760,9 +5762,6 @@ bool TallyResearchAverages_v9() if (pblockindex) { - if (fDebug3) - printf("Min block %i, Rows %i", pblockindex->nHeight, iRow); - StructCPID network = GetInitializedStructCPID2("NETWORK",mvNetworkCopy); network.projectname="NETWORK"; network.payments = NetworkPayments; From 87dbcd16e1330fe251e763265d926a1637c87afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 12:34:41 +0100 Subject: [PATCH 105/166] Done BlockNeedsChecked in CheckProofOfResearch another way. This covers reward too, not only magnitude. And in v9 the tally is stable, so no reason to skip checks. --- src/main.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2a583275da..ecef1231db 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -2165,11 +2165,16 @@ bool CheckProofOfResearch( int64_t nCoinAge = 0; int64_t nFees = 0; + bool fNeedsChecked = BlockNeedsChecked(block.nTime) || block.nVersion>=9; + + if(!fNeedsChecked) + return true; + // 6-4-2017 - Verify researchers stored block magnitude double dNeuralNetworkMagnitude = CalculatedMagnitude2(bb.cpid, block.nTime, false); - if (bb.Magnitude > 0 && - bb.Magnitude > (dNeuralNetworkMagnitude*1.25) && - (fTestNet || (!fTestNet && pindexPrev->nHeight > 947000))) + if( bb.Magnitude > 0 + && (fTestNet || (!fTestNet && pindexPrev->nHeight > 947000)) + && bb.Magnitude > (dNeuralNetworkMagnitude*1.25) ) { return error("CheckProofOfResearch: Researchers block magnitude > neural network magnitude: Block Magnitude %f, Neural Network Magnitude %f, CPID %s ", bb.Magnitude, dNeuralNetworkMagnitude, bb.cpid.c_str()); From e0f147dd080e1a57d2ac05b21f205e132ea09af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 12:37:18 +0100 Subject: [PATCH 106/166] Remove block client version checks in v9. --- src/main.cpp | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ecef1231db..c28c5620e1 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3867,26 +3867,29 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh return DoS(100, error("CheckBlock[] : more than one coinbase")); //Research Age MiningCPID bb = DeserializeBoincBlock(vtx[0].hashBoinc,nVersion); - //For higher security, plus lets catch these bad blocks before adding them to the chain to prevent reorgs: - if (bb.cpid != "INVESTOR" && IsProofOfStake() && height1 > nGrandfather && IsResearchAgeEnabled(height1) && BlockNeedsChecked(nTime) && !fLoadingIndex) + if(nVersion<9) { - double blockVersion = BlockVersion(bb.clientversion); - double cvn = ClientVersionNew(); - if (fDebug10) printf("BV %f, CV %f ",blockVersion,cvn); - // Enforce Beacon Age - if (blockVersion < 3588 && height1 > 860500 && !fTestNet) - return error("CheckBlock[]: Old client spamming new blocks after mandatory upgrade \r\n"); - } - - //Orphan Flood Attack - if (height1 > nGrandfather) - { - double bv = BlockVersion(bb.clientversion); - double cvn = ClientVersionNew(); - if (fDebug10) printf("BV %f, CV %f ",bv,cvn); - // Enforce Beacon Age - if (bv < 3588 && height1 > 860500 && !fTestNet) - return error("CheckBlock[]: Old client spamming new blocks after mandatory upgrade \r\n"); + //For higher security, plus lets catch these bad blocks before adding them to the chain to prevent reorgs: + if (bb.cpid != "INVESTOR" && IsProofOfStake() && height1 > nGrandfather && IsResearchAgeEnabled(height1) && BlockNeedsChecked(nTime) && !fLoadingIndex) + { + double blockVersion = BlockVersion(bb.clientversion); + double cvn = ClientVersionNew(); + if (fDebug10) printf("BV %f, CV %f ",blockVersion,cvn); + // Enforce Beacon Age + if (blockVersion < 3588 && height1 > 860500 && !fTestNet) + return error("CheckBlock[]: Old client spamming new blocks after mandatory upgrade \r\n"); + } + + //Orphan Flood Attack + if (height1 > nGrandfather) + { + double bv = BlockVersion(bb.clientversion); + double cvn = ClientVersionNew(); + if (fDebug10) printf("BV %f, CV %f ",bv,cvn); + // Enforce Beacon Age + if (bv < 3588 && height1 > 860500 && !fTestNet) + return error("CheckBlock[]: Old client spamming new blocks after mandatory upgrade \r\n"); + } } if (bb.cpid != "INVESTOR" && height1 > nGrandfather && BlockNeedsChecked(nTime)) From 33581bc0abe699f007f6303966eb2dcf88acabf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 12:38:30 +0100 Subject: [PATCH 107/166] Reorder GridcoinServices to not skip tally when out of sync. --- src/main.cpp | 142 ++++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 70 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c28c5620e1..ee04e5ad7a 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4271,65 +4271,8 @@ void GridcoinServices() uiInterface.NotifyBlocksChanged(); } #endif - // Services thread activity - - //Dont perform the following functions if out of sync - if (pindexBest->nHeight < nGrandfather) return; - - if (OutOfSyncByAge()) return; - if (fDebug) printf(" {SVC} "); - - //Backup the wallet once per 900 blocks or as specified in config: - int nWBI = GetArg("-walletbackupinterval", 900); - if (nWBI == 0) - nWBI = 900; - if (TimerMain("backupwallet", nWBI)) - { - bool bWalletBackupResults = BackupWallet(*pwalletMain, GetBackupFilename("wallet.dat")); - bool bConfigBackupResults = BackupConfigFile(GetBackupFilename("gridcoinresearch.conf")); - printf("Daily backup results: Wallet -> %s Config -> %s\r\n", (bWalletBackupResults ? "true" : "false"), (bConfigBackupResults ? "true" : "false")); - } - - if (TimerMain("ResetVars",30)) - { - bTallyStarted_retired = false; - } - - if (false && TimerMain("FixSpentCoins",60)) - { - int nMismatchSpent; - int64_t nBalanceInQuestion; - pwalletMain->FixSpentCoins(nMismatchSpent, nBalanceInQuestion); - } - - if (TimerMain("MyNeuralMagnitudeReport",30)) - { - try - { - if (msNeuralResponse.length() < 25 && msPrimaryCPID != "INVESTOR" && !msPrimaryCPID.empty()) - { - AsyncNeuralRequest("explainmag",msPrimaryCPID,5); - if (fDebug3) printf("Async explainmag sent for %s.",msPrimaryCPID.c_str()); - } - // Run the RSA report for the overview page: - if (!msPrimaryCPID.empty() && msPrimaryCPID != "INVESTOR") - { - if (fDebug3) printf("updating rsa\r\n"); - MagnitudeReport(msPrimaryCPID); - if (fDebug3) printf("updated rsa\r\n"); - } - if (fDebug3) printf("\r\n MR Complete \r\n"); - } - catch (std::exception &e) - { - printf("Error in MyNeuralMagnitudeReport1."); - } - catch(...) - { - printf("Error in MyNeuralMagnitudeReport."); - } - } + // Services thread activity if(IsV9Enabled_Tally(nBestHeight)) { @@ -4398,7 +4341,77 @@ void GridcoinServices() } } } - + + if (false && TimerMain("GridcoinPersistedDataSystem",5)) + { + std::string errors1 = ""; + LoadAdminMessages(false,errors1); + } + + if (TimerMain("clearcache",1000)) + { + ClearCache("neural_data"); + } + + + //Dont perform the following functions if out of sync + if (pindexBest->nHeight < nGrandfather && OutOfSyncByAge()) + return; + + if (fDebug) printf(" {SVC} "); + + //Backup the wallet once per 900 blocks or as specified in config: + int nWBI = GetArg("-walletbackupinterval", 900); + if (nWBI == 0) + nWBI = 900; + + if (TimerMain("backupwallet", nWBI)) + { + bool bWalletBackupResults = BackupWallet(*pwalletMain, GetBackupFilename("wallet.dat")); + bool bConfigBackupResults = BackupConfigFile(GetBackupFilename("gridcoinresearch.conf")); + printf("Daily backup results: Wallet -> %s Config -> %s\r\n", (bWalletBackupResults ? "true" : "false"), (bConfigBackupResults ? "true" : "false")); + } + + if (TimerMain("ResetVars",30)) + { + bTallyStarted_retired = false; + } + + if (false && TimerMain("FixSpentCoins",60)) + { + int nMismatchSpent; + int64_t nBalanceInQuestion; + pwalletMain->FixSpentCoins(nMismatchSpent, nBalanceInQuestion); + } + + if (TimerMain("MyNeuralMagnitudeReport",30)) + { + try + { + if (msNeuralResponse.length() < 25 && msPrimaryCPID != "INVESTOR" && !msPrimaryCPID.empty()) + { + AsyncNeuralRequest("explainmag",msPrimaryCPID,5); + if (fDebug3) printf("Async explainmag sent for %s.",msPrimaryCPID.c_str()); + } + // Run the RSA report for the overview page: + if (!msPrimaryCPID.empty() && msPrimaryCPID != "INVESTOR") + { + if (fDebug3) printf("updating rsa\r\n"); + MagnitudeReport(msPrimaryCPID); + if (fDebug3) printf("updated rsa\r\n"); + } + if (fDebug3) printf("\r\n MR Complete \r\n"); + } + catch (std::exception &e) + { + printf("Error in MyNeuralMagnitudeReport1."); + } + catch(...) + { + printf("Error in MyNeuralMagnitudeReport."); + } + } + // Every N blocks as a Synchronized TEAM: if ((nBestHeight % 30) == 0) { @@ -4451,12 +4464,6 @@ void GridcoinServices() } } - if (false && TimerMain("GridcoinPersistedDataSystem",5)) - { - std::string errors1 = ""; - LoadAdminMessages(false,errors1); - } - if (KeyEnabled("exportmagnitude")) { if (TimerMain("export_magnitude",900)) @@ -4475,11 +4482,6 @@ void GridcoinServices() msNeuralResponse=""; } - if (TimerMain("clearcache",1000)) - { - ClearCache("neural_data"); - } - if (TimerMain("check_for_autoupgrade",240)) { if (fDebug3) printf("Checking for upgrade..."); From 307e848dc054b30657d93dfef9eb28929106bd47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 12:39:23 +0100 Subject: [PATCH 108/166] Change debug messages --- src/main.cpp | 3 +-- src/rpcblockchain.cpp | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ee04e5ad7a..2313be8591 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5559,7 +5559,6 @@ bool TallyResearchAverages_retired(bool Forcefully) int64_t nStart = GetTimeMillis(); lastTallied = GetAdjustedTime(); - if (fDebug) printf("Tallying Research Averages (begin) "); bNetAveragesLoaded = false; bool superblockloaded = false; double NetworkPayments = 0; @@ -5571,7 +5570,7 @@ bool TallyResearchAverages_retired(bool Forcefully) int nMinDepth = (nMaxDepth - nLookback) - ( (nMaxDepth-nLookback) % BLOCK_GRANULARITY); if (fDebug3) printf("START BLOCK %f, END BLOCK %f ",(double)nMaxDepth,(double)nMinDepth); if (nMinDepth < 2) nMinDepth = 2; - if(fDebug) printf("TallyResearchAverages_retired: start %d end %d\n",nMaxDepth,nMinDepth); + if(fDebug) printf("TallyResearchAverages_retired: beginning start %d end %d\n",nMaxDepth,nMinDepth); mvMagnitudesCopy.clear(); int iRow = 0; //CBlock block; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 933528b579..02c4c79ebe 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -785,6 +785,8 @@ bool TallyMagnitudesInSuperblock() network.projectname="NETWORK"; network.NetworkMagnitude = TotalNetworkMagnitude; network.NetworkAvgMagnitude = NetworkAvgMagnitude; + if (fDebug) + printf("TallyMagnitudesInSuperblock: Extracted %.0f magnitude entries from cached superblock %s\n", TotalNetworkEntries,ReadCache("superblock","block_number").c_str()); double TotalProjects = 0; double TotalRAC = 0; From 77b5ebe1c5333b032d1c8f42ae8ffee345cf0e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 15:19:25 +0100 Subject: [PATCH 109/166] Fix miner to produce v8 kernels for v9 blocks. --- src/miner.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index aa7c7021dc..fc9eab5fd9 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -504,7 +504,7 @@ bool CreateCoinStake( CBlock &blocknew, CKey &key, CoinWeight = CalculateStakeWeightV3(CoinTx,CoinTxN,GlobalCPUMiningCPID); StakeKernelHash= CalculateStakeHashV3(CoinBlock,CoinTx,CoinTxN,txnew.nTime,GlobalCPUMiningCPID,mdPORNonce); } - else if(blocknew.nVersion==8) + else { uint64_t StakeModifier = 0; if(!FindStakeModifierRev(StakeModifier,pindexPrev)) @@ -512,7 +512,6 @@ bool CreateCoinStake( CBlock &blocknew, CKey &key, CoinWeight = CalculateStakeWeightV8(CoinTx,CoinTxN,GlobalCPUMiningCPID); StakeKernelHash= CalculateStakeHashV8(CoinBlock,CoinTx,CoinTxN,txnew.nTime,StakeModifier,GlobalCPUMiningCPID); } - else return false; CBigNum StakeTarget; StakeTarget.SetCompact(blocknew.nBits); From a2d221ec48a28001490e673e51b1e88f9121ce58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 15:20:25 +0100 Subject: [PATCH 110/166] Disable tally rate limiting. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 2313be8591..056a916e4d 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5466,7 +5466,7 @@ bool ComputeNeuralNetworkSupermajorityHashes() if (nBestHeight < 15) return true; if (IsLockTimeWithinMinutes(nLastTalliedNeural,5)) { - return true; + //return true; } nLastTalliedNeural = GetAdjustedTime(); //Clear the neural network hash buffer From b8584254be1c8c3bbefc5e67a1317b3fd475f646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Mon, 30 Oct 2017 17:19:22 +0100 Subject: [PATCH 111/166] Bump testnet v9 trigger. --- src/main.cpp | 3 +-- src/main.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 056a916e4d..7c0d4799a9 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3188,8 +3188,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo // Prevent duplicate superblocks if(nVersion >= 9 && !NeedASuperblock()) return error(("ConnectBlock: SuperBlock rcvd, but not Needed (too early)")); - - // Always perform SB checks in v9 + if ((pindex->nHeight > nGrandfather && !fReorganizing) || pindex->nVersion >= 9 ) { // 12-20-2015 : Add support for Binary Superblocks diff --git a/src/main.h b/src/main.h index fd517eab7c..4941e2ddab 100755 --- a/src/main.h +++ b/src/main.h @@ -99,7 +99,7 @@ inline uint32_t IsV8Enabled(int nHeight) inline uint32_t IsV9Enabled(int nHeight) { return fTestNet - ? nHeight >= 378600 + ? nHeight >= 392570 : nHeight >= 2000000; } From d046efa3d1d607f383cf8c2679d812b21638a021 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 5 Nov 2017 16:11:02 +0100 Subject: [PATCH 112/166] Dead code removal. --- src/main.cpp | 13 ------------- src/main.h | 1 - 2 files changed, 14 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7c0d4799a9..0c562ba98a 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -150,8 +150,6 @@ unsigned int WHITELISTED_PROJECTS = 0; int64_t nLastPing = 0; int64_t nLastAskedForBlocks = 0; int64_t nBootup = 0; - -int64_t nLastTalliedNeural = 0; int64_t nLastLoadAdminMessages = 0; int64_t nCPIDsLoaded = 0; int64_t nLastGRCtallied = 0; @@ -4341,12 +4339,6 @@ void GridcoinServices() } } - if (false && TimerMain("GridcoinPersistedDataSystem",5)) - { - std::string errors1 = ""; - LoadAdminMessages(false,errors1); - } - if (TimerMain("clearcache",1000)) { ClearCache("neural_data"); @@ -5463,11 +5455,6 @@ StructCPID GetInitializedStructCPID2(const std::string& name, std::map 0) mvNeuralNetworkHash.clear(); if (mvNeuralVersion.size() > 0) mvNeuralVersion.clear(); diff --git a/src/main.h b/src/main.h index 4941e2ddab..c92b6cb2b6 100755 --- a/src/main.h +++ b/src/main.h @@ -173,7 +173,6 @@ extern int64_t nMinimumInputValue; extern int64_t nLastPing; extern int64_t nLastAskedForBlocks; extern int64_t nBootup; -extern int64_t nLastTalliedNeural; extern int64_t nCPIDsLoaded; extern int64_t nLastGRCtallied; extern int64_t nLastCleaned; From cbfd76be0ac1060b8ecc6b4d4dd36bd1da587ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 16:27:36 +0100 Subject: [PATCH 113/166] Fix kernel to accept v9 blocks as v8 kernel. --- src/kernel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index 6148eba2fc..8f7dea1aaf 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -886,7 +886,7 @@ bool CheckProofOfStakeV8( CTransaction *p_coinstake; - if(Block.nVersion==8) { + if(Block.nVersion>=8 && Block.nVersion<=9) { if (!Block.IsProofOfStake()) return error("CheckProofOfStakeV8() : called on non-coinstake block %s", Block.GetHash().ToString().c_str()); p_coinstake = &Block.vtx[1]; From 42911e225f04d037f0904dd6a2609460e4d98574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 16:44:10 +0100 Subject: [PATCH 114/166] Really disable the tally rate limit. This reverts commit 973e453b2d31152a808283a2a43f0c91b9308c28. --- src/main.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0c562ba98a..6c27b314e9 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -5533,17 +5533,8 @@ bool TallyResearchAverages_retired(bool Forcefully) return true; } - static int64_t lastTallied = 0; - int timespan = fTestNet ? 2 : 6; - if (IsLockTimeWithinMinutes(lastTallied,timespan)) - { - bNetAveragesLoaded = true; - return true; - } - //8-27-2016 int64_t nStart = GetTimeMillis(); - lastTallied = GetAdjustedTime(); bNetAveragesLoaded = false; bool superblockloaded = false; @@ -5638,13 +5629,11 @@ bool TallyResearchAverages_retired(bool Forcefully) { printf("Bad Alloc while tallying network averages. [1]\r\n"); bNetAveragesLoaded=true; - lastTallied = 0; } catch(...) { printf("Error while tallying network averages. [1]\r\n"); bNetAveragesLoaded=true; - lastTallied = 0; } if (fDebug3) printf("NA loaded in %f",(double)GetTimeMillis()-nStart); From 9d13a5957696e7083112ba0d59e6cf4bf01641e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 5 Nov 2017 16:48:08 +0100 Subject: [PATCH 115/166] Fix misleading warning message in historical magnitude. --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6c27b314e9..c2bc20472f 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -8657,9 +8657,9 @@ CBlockIndex* GetHistoricalMagnitude(std::string cpid) return pindexGenesisBlock; CBlockIndex* pblockindex = mapItem->second; - if(!pblockindex->pnext) - printf("GetHistoricalMagnitude: WARNING index {%s %d} for cpid %s, " - "has no next pointer (not n main chain)\n",pblockindex->GetBlockHash().GetHex().c_str(), + if(!pblockindex->pnext && pblockindex!=pindexBest) + printf("WARNING GetHistoricalMagnitude: index {%s %d} for cpid %s, " + "is not in the main chain\n",pblockindex->GetBlockHash().GetHex().c_str(), pblockindex->nHeight,cpid.c_str()); if (pblockindex->nHeight < nMinIndex) { From 0571e14c0e118fb0c080782da9b36443fa6c512d Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Tue, 7 Nov 2017 03:58:54 -0800 Subject: [PATCH 116/166] Use IsReseacher, refactor where needed, eliminate DetermineCPIDType. (#721) * Use IsResearcher instead of doing manual comparisons * Remove DetermineCPIDType from kernel.cpp as its not used there and removed it from main.cpp check as it is the only place it calls for the function and only checks if its a researcher cpid. so IsResearcher can replace that. * Add tests for IsResearcher. --- src/kernel.cpp | 52 +++-------- src/main.cpp | 47 +++++----- src/miner.cpp | 2 +- src/rpcblockchain.cpp | 168 ++++++++++++++++++------------------ src/test/gridcoin_tests.cpp | 22 +++++ src/wallet.cpp | 3 +- 6 files changed, 143 insertions(+), 151 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index 8f7dea1aaf..694f84013b 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -12,7 +12,6 @@ bool IsCPIDValidv2(MiningCPID& mc,int height); using namespace std; StructCPID GetStructCPID(); extern int64_t GetRSAWeightByCPID(std::string cpid); -extern int DetermineCPIDType(std::string cpid); extern int64_t GetRSAWeightByCPIDWithRA(std::string cpid); double MintLimiter(double PORDiff,int64_t RSA_WEIGHT,std::string cpid,int64_t locktime); extern double GetLastPaymentTimeByCPID(std::string cpid); @@ -277,38 +276,13 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifi // a proof-of-work situation. // -int DetermineCPIDType(std::string cpid) -{ - // -1 = Invalid CPID - // 1 = Valid CPID with RAC - // 2 = Investor or Pool Miner - printf("\r\nCPID Length %f\r\n",(double)cpid.length()); - - if (cpid.empty()) return -1; - if (cpid=="INVESTOR") return 2; - StructCPID h = mvMagnitudes[cpid]; - if (h.Magnitude > 0) return 1; - // If magnitude is 0 in the current superblock, try to get magnitude from netsoft before failing - if (cpid.length()==32) - { - return 1; - } - else - { - // CPID is not 32 chars long- return Investor - return 2; - } -} - - double GetMagnitudeByHashBoinc(std::string hashBoinc, int height) { if (hashBoinc.length() > 1) { // block version not needed for now for mag MiningCPID boincblock = DeserializeBoincBlock(hashBoinc,7); - if (boincblock.cpid == "" || boincblock.cpid.length() < 6) return 0; //Block has no CPID - if (boincblock.cpid == "INVESTOR") return 0; + if (!IsResearcher(boincblock.cpid)) return 0; if (boincblock.projectname == "") return 0; if (boincblock.rac < 100) return 0; if (!IsCPIDValidv2(boincblock,height)) return 0; @@ -321,7 +295,7 @@ int64_t GetRSAWeightByCPIDWithRA(std::string cpid) { //Requires Magnitude > 0, be in superblock, with a lifetime cpid paid = 0 //12-3-2015 - if (cpid.empty() || cpid=="INVESTOR") + if (!IsResearcher(cpid)) return 0; double dWeight = 0; @@ -345,7 +319,7 @@ int64_t GetRSAWeightByCPID(std::string cpid) double weight = 0; - if (cpid=="" || cpid=="INVESTOR") return 5000; + if (!IsResearcher(cpid)) return 5000; if (mvMagnitudes.size() > 0) { StructCPID UntrustedHost = GetStructCPID(); @@ -367,7 +341,7 @@ int64_t GetRSAWeightByCPID(std::string cpid) } else { - if (cpid.length() > 5 && cpid != "INVESTOR") + if (IsResearcher(cpid)) { weight = 25000; } @@ -375,7 +349,7 @@ int64_t GetRSAWeightByCPID(std::string cpid) } else { - if (cpid.length() > 5 && cpid != "INVESTOR") + if (IsResearcher(cpid)) { weight = 5000; } @@ -403,7 +377,7 @@ double GetLastPaymentTimeByCPID(std::string cpid) } else { - if (cpid.length() > 5 && cpid != "INVESTOR") + if (IsResearcher(cpid)) { lpt = 0; } @@ -411,7 +385,7 @@ double GetLastPaymentTimeByCPID(std::string cpid) } else { - if (cpid.length() > 5 && cpid != "INVESTOR") + if (IsResearcher(cpid)) { lpt=0; } @@ -422,7 +396,7 @@ double GetLastPaymentTimeByCPID(std::string cpid) int64_t GetRSAWeightByBlock(MiningCPID boincblock) { int64_t rsa_weight = 0; - if (boincblock.cpid != "INVESTOR") + if (IsResearcher(boincblock.cpid)) { rsa_weight = boincblock.RSAWeight + boincblock.Magnitude; } @@ -448,7 +422,7 @@ double GetUntrustedMagnitude(std::string cpid, double& out_owed) } else { - if (cpid.length() > 5 && cpid != "INVESTOR") + if (IsResearcher(cpid)) { out_owed = 0; } @@ -456,7 +430,7 @@ double GetUntrustedMagnitude(std::string cpid, double& out_owed) } else { - if (cpid.length() > 5 && cpid != "INVESTOR") + if (IsResearcher(cpid)) { out_owed = 0; } @@ -511,7 +485,7 @@ static bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom, double coin_age = std::abs((double)nTimeTx-(double)txPrev.nTime); double payment_age = std::abs((double)nTimeTx-(double)boincblock.LastPaymentTime); - if ((payment_age > 60*60) && boincblock.Magnitude > 1 && boincblock.cpid != "INVESTOR" && (coin_age > 4*60*60) && (coin_age > RSA_WEIGHT) + if ((payment_age > 60*60) && boincblock.Magnitude > 1 && IsResearcher(boincblock.cpid) && (coin_age > 4*60*60) && (coin_age > RSA_WEIGHT) && (RSA_WEIGHT/14 > MintLimiter(PORDiff,RSA_WEIGHT,boincblock.cpid,nTimeTx)) ) { //Coins are older than RSA balance @@ -536,7 +510,7 @@ static bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom, uint64_t nStakeModifier = 0; int nStakeModifierHeight = 0; int64_t nStakeModifierTime = 0; - if (boincblock.cpid=="INVESTOR") + if (!IsResearcher(boincblock.cpid)) { if (!GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake)) { @@ -650,7 +624,7 @@ static bool CheckStakeKernelHashV3(CBlockIndex* pindexPrev, unsigned int nBits, double BitsAge = PORDiff * 144; //For every 100 Diff in Bits, two hours of coin age for researchers if (BitsAge > 86400) BitsAge=86400; //Limit to 24 hours (possibility of astronomical diff) - if (boincblock.cpid != "INVESTOR") { + if (IsResearcher(boincblock.cpid)) { if (checking_local && RSA_WEIGHT >= 24999 && boincblock.Magnitude > .25) msMiningErrors7="Newbie block being generated."; // Halford : Explain to the Researcher why they are not staking: diff --git a/src/main.cpp b/src/main.cpp index a4b30ff83d..5cea00e5ad 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,7 +55,6 @@ extern bool TallyResearchAverages_retired(bool Forcefully); extern bool TallyNetworkAverages_v9(); extern void IncrementCurrentNeuralNetworkSupermajority(std::string NeuralHash, std::string GRCAddress, double distance); bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature); -int DetermineCPIDType(std::string cpid); extern MiningCPID GetInitializedMiningCPID(std::string name, std::map& vRef); std::string GetListOfWithConsensus(std::string datatype); extern std::string getHardDriveSerial(); @@ -759,7 +758,7 @@ MiningCPID GetNextProject(bool bForce) GlobalCPUMiningCPID.Magnitude = CalculatedMagnitude(GetAdjustedTime(),false); if (fDebug && LessVerbose(2)) printf("For CPID %s Verified Magnitude = %f",GlobalCPUMiningCPID.cpid.c_str(),GlobalCPUMiningCPID.Magnitude); //Reserved for GRC Speech Synthesis - msMiningErrors = (msMiningCPID == "INVESTOR" || msPrimaryCPID=="INVESTOR" || msMiningCPID.empty() || msPrimaryCPID.empty()) ? _("Staking Interest") : _("Boinc Mining"); + msMiningErrors = (msMiningCPID == "INVESTOR" || !IsResearcher(msPrimaryCPID) || msMiningCPID.empty()) ? _("Staking Interest") : _("Boinc Mining"); GlobalCPUMiningCPID.RSAWeight = GetRSAWeightByCPID(GlobalCPUMiningCPID.cpid); GlobalCPUMiningCPID.LastPaymentTime = GetLastPaymentTimeByCPID(GlobalCPUMiningCPID.cpid); return GlobalCPUMiningCPID; @@ -775,7 +774,7 @@ MiningCPID GetNextProject(bool bForce) } } - msMiningErrors = (msPrimaryCPID == "INVESTOR") ? "" : _("All BOINC projects exhausted."); + msMiningErrors = (IsResearcher(msPrimaryCPID)) ? _("All BOINC projects exhausted.") : ""; msMiningProject = "INVESTOR"; msMiningCPID = "INVESTOR"; GlobalCPUMiningCPID = GetInitializedGlobalCPUMiningCPID("INVESTOR"); @@ -3020,7 +3019,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo if (bb.ResearchSubsidy > dMaxResearchAgeReward && IsResearchAgeEnabled(pindex->nHeight)) return DoS(1, error("ConnectBlock[ResearchAge] : Coinstake pays above maximum (actual= %f, vs calculated=%f )", dStakeRewardWithoutFees, dMaxResearchAgeReward)); - if (bb.cpid=="INVESTOR" && dStakeReward > 1) + if (!IsResearcher(bb.cpid) && dStakeReward > 1) { double OUT_POR = 0; double OUT_INTEREST_OWED = 0; @@ -3095,7 +3094,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo // ResearchAge 1: GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 1, nTime, pindex, "connectblock_researcher", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); - if (bb.cpid != "INVESTOR" && dStakeReward > 1) + if (IsResearcher(bb.cpid) && dStakeReward > 1) { //ResearchAge: Since the best block may increment before the RA is connected but After the RA is computed, the ResearchSubsidy can sometimes be slightly smaller than we calculate here due to the RA timespan increasing. So we will allow for time shift before rejecting the block. @@ -3147,7 +3146,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo } //Approve first coinstake in DPOR block - if (bb.cpid != "INVESTOR" && IsLockTimeWithinMinutes(GetBlockTime(),15) && !IsResearchAgeEnabled(pindex->nHeight)) + if (IsResearcher(bb.cpid) && IsLockTimeWithinMinutes(GetBlockTime(),15) && !IsResearchAgeEnabled(pindex->nHeight)) { if (bb.ResearchSubsidy > (GetOwedAmount(bb.cpid)+1)) { @@ -3279,7 +3278,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo // End of Network Consensus // Gridcoin: Track payments to CPID, and last block paid - if (!bb.cpid.empty() && bb.cpid != "INVESTOR" && pindex->nHeight > nNewIndex2) + if (IsResearcher(bb.cpid) && pindex->nHeight > nNewIndex2) { StructCPID stCPID = GetInitializedStructCPID2(bb.cpid,mvResearchAge); stCPID.InterestSubsidy += bb.InterestSubsidy; @@ -3867,7 +3866,7 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh if(nVersion<9) { //For higher security, plus lets catch these bad blocks before adding them to the chain to prevent reorgs: - if (bb.cpid != "INVESTOR" && IsProofOfStake() && height1 > nGrandfather && IsResearchAgeEnabled(height1) && BlockNeedsChecked(nTime) && !fLoadingIndex) + if (IsResearcher(bb.cpid) && IsProofOfStake() && height1 > nGrandfather && IsResearchAgeEnabled(height1) && BlockNeedsChecked(nTime) && !fLoadingIndex) { double blockVersion = BlockVersion(bb.clientversion); double cvn = ClientVersionNew(); @@ -3889,7 +3888,7 @@ bool CBlock::CheckBlock(std::string sCaller, int height1, int64_t Mint, bool fCh } } - if (bb.cpid != "INVESTOR" && height1 > nGrandfather && BlockNeedsChecked(nTime)) + if (IsResearcher(bb.cpid) && height1 > nGrandfather && BlockNeedsChecked(nTime)) { if (bb.projectname.empty() && !IsResearchAgeEnabled(height1)) return DoS(1,error("CheckBlock::PoR Project Name invalid")); @@ -4379,13 +4378,13 @@ void GridcoinServices() { try { - if (msNeuralResponse.length() < 25 && msPrimaryCPID != "INVESTOR" && !msPrimaryCPID.empty()) + if (msNeuralResponse.length() < 25 && IsResearcher(msPrimaryCPID)) { AsyncNeuralRequest("explainmag",msPrimaryCPID,5); if (fDebug3) printf("Async explainmag sent for %s.",msPrimaryCPID.c_str()); } // Run the RSA report for the overview page: - if (!msPrimaryCPID.empty() && msPrimaryCPID != "INVESTOR") + if (IsResearcher(msPrimaryCPID)) { if (fDebug3) printf("updating rsa\r\n"); MagnitudeReport(msPrimaryCPID); @@ -5087,13 +5086,13 @@ bool IsCPIDValidv2(MiningCPID& mc, int height) } else if (height >= cpidV2CutOverHeight && height <= cpidV3CutOverHeight) { - if (mc.cpid == "INVESTOR" || mc.cpid=="investor") return true; + if (!IsResearcher(mc.cpid)) return true; result = CPID_IsCPIDValid(mc.cpid, mc.cpidv2, (uint256)mc.lastblockhash); } else if (height >= cpidV3CutOverHeight) { - if (mc.cpid == "INVESTOR" || mc.cpid=="investor") return true; if (mc.cpid.empty()) return false; + if (!IsResearcher(mc.cpid)) return true; // V3 requires a beacon, a beacon public key and a valid block signature signed by the CPID's private key result = VerifyCPIDSignature(mc.cpid,mc.lastblockhash,mc.BoincSignature); } @@ -5122,7 +5121,7 @@ bool IsCPIDValid_Retired(std::string cpid, std::string ENCboincpubkey) printf("CPID length empty."); return false; } - if (cpid=="INVESTOR") return true; + if (!IsResearcher(cpid)) return true; if (ENCboincpubkey == "" || ENCboincpubkey.length() < 5) { if (fDebug10) printf("ENCBpk length empty."); @@ -5311,7 +5310,7 @@ bool GetEarliestStakeTime(std::string grcaddress, std::string cpid) { myCPID = pblockindex->GetCPID(); } - if (cpid == myCPID && nCPIDTime==0 && myCPID != "INVESTOR") + if (cpid == myCPID && nCPIDTime==0 && IsResearcher(myCPID)) { nCPIDTime = pblockindex->nTime; nGRCTime = pblockindex->nTime; @@ -5321,7 +5320,7 @@ bool GetEarliestStakeTime(std::string grcaddress, std::string cpid) } int64_t EarliestStakedWalletTx = GetEarliestWalletTransaction(); if (EarliestStakedWalletTx > 0 && EarliestStakedWalletTx < nGRCTime) nGRCTime = EarliestStakedWalletTx; - if (cpid=="INVESTOR" && EarliestStakedWalletTx > 0) nGRCTime = EarliestStakedWalletTx; + if (!IsResearcher(cpid) && EarliestStakedWalletTx > 0) nGRCTime = EarliestStakedWalletTx; if (fTestNet) nGRCTime -= (86400*30); if (nGRCTime <= 0) nGRCTime = GetAdjustedTime(); if (nCPIDTime <= 0) nCPIDTime = GetAdjustedTime(); @@ -5350,7 +5349,7 @@ void AddCPIDBlockHash(const std::string& cpid, const uint256& blockhash) StructCPID GetLifetimeCPID(const std::string& cpid, const std::string& sCalledFrom) { //Eliminates issues with reorgs, disconnects, double counting, etc.. - if (cpid.empty() || cpid=="INVESTOR") + if (!IsResearcher(cpid)) return GetInitializedStructCPID2("INVESTOR",mvResearchAge); if (fDebug10) printf("GetLifetimeCPID.BEGIN: %s %s",sCalledFrom.c_str(),cpid.c_str()); @@ -7260,7 +7259,7 @@ std::string SerializeBoincBlock(MiningCPID mcpid, int BlockVersion) if (mcpid.lastblockhash.empty()) mcpid.lastblockhash = "0"; if (mcpid.LastPORBlockHash.empty()) mcpid.LastPORBlockHash="0"; - if (!mcpid.cpid.empty() && mcpid.cpid != "INVESTOR" && mcpid.lastblockhash != "0") + if (IsResearcher(mcpid.cpid) && mcpid.lastblockhash != "0") { mcpid.BoincPublicKey = GetBeaconPublicKey(mcpid.cpid, false); } @@ -7713,12 +7712,8 @@ void HarvestCPIDs(bool cleardata) if (structcpid.Iscpidvalid) { - // Verify the CPID has magnitude > 0, otherwise set the user as an investor: - int iCPIDType = DetermineCPIDType(structcpid.cpid); - // -1 = Invalid CPID - // 1 = Valid CPID with RAC - // 2 = Investor or Pool Miner - if (iCPIDType==1) + // Verify the CPID is a valid researcher: + if (IsResearcher(structcpid.cpid)) { GlobalCPUMiningCPID.cpidhash = cpidhash; GlobalCPUMiningCPID.email = email; @@ -8504,7 +8499,7 @@ bool UnusualActivityReport() { std::string hb = block.vtx[0].hashBoinc; MiningCPID bb = DeserializeBoincBlock(hb,block.nVersion); - if (bb.cpid != "INVESTOR") + if (IsResearcher(bb.cpid)) { printf("Block #%f:%f, Recipient %s, CPID %s, Paid %f, StakeReward %f \r\n",(double)ii,(double)0, bb.GRCAddress.c_str(), bb.cpid.c_str(), subsidy,(double)nStakeReward); @@ -8651,7 +8646,7 @@ int64_t ComputeResearchAccrual(int64_t nTime, std::string cpid, std::string oper CBlockIndex* GetHistoricalMagnitude(std::string cpid) { - if (cpid=="INVESTOR") return pindexGenesisBlock; + if (!IsResearcher(cpid)) return pindexGenesisBlock; // Starting at the block prior to StartHeight, find the last instance of the CPID in the chain: // Limit lookback to 6 months diff --git a/src/miner.cpp b/src/miner.cpp index fc9eab5fd9..bfe6a876bd 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -791,7 +791,7 @@ bool IsMiningAllowed(CWallet *pwallet) { LOCK(MinerStatus.lock); MinerStatus.ReasonNotStaking+="Net averages not yet loaded; "; - if (LessVerbose(100) && msPrimaryCPID != "INVESTOR") printf("ResearchMiner:Net averages not yet loaded..."); + if (LessVerbose(100) && IsResearcher(msPrimaryCPID)) printf("ResearchMiner:Net averages not yet loaded..."); status=false; } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 02c4c79ebe..94f91a79fa 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -289,7 +289,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPri uint256 blockhash = block.GetPoWHash(); std::string sblockhash = blockhash.GetHex(); bool IsPoR = false; - IsPoR = (bb.Magnitude > 0 && bb.cpid != "INVESTOR" && blockindex->IsProofOfStake()); + IsPoR = (bb.Magnitude > 0 && IsResearcher(bb.cpid) && blockindex->IsProofOfStake()); std::string PoRNarr = ""; if (IsPoR) PoRNarr = "proof-of-research"; result.push_back(Pair("flags", @@ -949,7 +949,7 @@ bool AdvertiseBeacon(std::string &sOutPrivKey, std::string &sOutPubKey, std::str LOCK(cs_main); { GetNextProject(false); - if (GlobalCPUMiningCPID.cpid=="INVESTOR") + if (!IsResearcher(GlobalCPUMiningCPID.cpid)) { sError = "INVESTORS_CANNOT_SEND_BEACONS"; return false; @@ -2697,7 +2697,7 @@ Array MagnitudeReport(std::string cpid) entry.push_back(Pair("Tx Count",(int)stCPID.Accuracy)); results.push_back(entry); - if (cpid==msPrimaryCPID && !msPrimaryCPID.empty() && msPrimaryCPID != "INVESTOR") + if (cpid==msPrimaryCPID && IsResearcher(msPrimaryCPID)) { msRSAOverview = "Exp PPD: " + RoundToString(dExpected14/14,0) + ", Act PPD: " + RoundToString(structMag.payments/14,0) @@ -2783,7 +2783,7 @@ std::string TimestampToHRDate(double dtm) double GetMagnitudeByCpidFromLastSuperblock(std::string sCPID) { StructCPID structMag = mvMagnitudes[sCPID]; - if (structMag.initialized && structMag.cpid.length() > 2 && structMag.cpid != "INVESTOR") + if (structMag.initialized && IsResearcher(structMag.cpid)) { return structMag.Magnitude; } @@ -2990,34 +2990,34 @@ std::string GetShareType(double dShareType) std::string GetProvableVotingWeightXML() { - std::string sXML = ""; - //Retrieve the historical magnitude - if (!msPrimaryCPID.empty() && msPrimaryCPID != "INVESTOR") - { - StructCPID st1 = GetLifetimeCPID(msPrimaryCPID,"ProvableMagnitude()"); - CBlockIndex* pHistorical = GetHistoricalMagnitude(msPrimaryCPID); - if (pHistorical->nHeight > 1 && pHistorical->nMagnitude > 0) - { - std::string sBlockhash = pHistorical->GetBlockHash().GetHex(); - std::string sSignature = SignBlockWithCPID(msPrimaryCPID,pHistorical->GetBlockHash().GetHex()); - // Find the Magnitude from the last staked block, within the last 6 months, and ensure researcher has a valid current beacon (if the beacon is expired, the signature contain an error message) - sXML += "" + msPrimaryCPID + "" - + RoundToString(pHistorical->nMagnitude,2) + "" + - "" + ToString(pHistorical->nHeight) - + "" + sBlockhash + "" + sSignature + ""; - } - } - sXML += ""; + std::string sXML = ""; + //Retrieve the historical magnitude + if (IsResearcher(msPrimaryCPID)) + { + StructCPID st1 = GetLifetimeCPID(msPrimaryCPID,"ProvableMagnitude()"); + CBlockIndex* pHistorical = GetHistoricalMagnitude(msPrimaryCPID); + if (pHistorical->nHeight > 1 && pHistorical->nMagnitude > 0) + { + std::string sBlockhash = pHistorical->GetBlockHash().GetHex(); + std::string sSignature = SignBlockWithCPID(msPrimaryCPID,pHistorical->GetBlockHash().GetHex()); + // Find the Magnitude from the last staked block, within the last 6 months, and ensure researcher has a valid current beacon (if the beacon is expired, the signature contain an error message) + sXML += "" + msPrimaryCPID + "" + + RoundToString(pHistorical->nMagnitude,2) + "" + + "" + ToString(pHistorical->nHeight) + + "" + sBlockhash + "" + sSignature + ""; + } + } + sXML += ""; vector vecOutputs; pwalletMain->AvailableCoins(vecOutputs, false, NULL, true); - std::string sRow = ""; - double dTotal = 0; - double dBloatThreshhold = 100; - double dCurrentItemCount = 0; - double dItemBloatThreshhold = 50; - // Iterate unspent coins from transactions owned by me that total over 100GRC (this prevents XML bloat) - sXML += ""; + std::string sRow = ""; + double dTotal = 0; + double dBloatThreshhold = 100; + double dCurrentItemCount = 0; + double dItemBloatThreshhold = 50; + // Iterate unspent coins from transactions owned by me that total over 100GRC (this prevents XML bloat) + sXML += ""; for (auto const& out : vecOutputs) { int64_t nValue = out.tx->vout[out.i].nValue; @@ -3068,9 +3068,9 @@ std::string GetProvableVotingWeightXML() } - sXML += "" + RoundToString(dTotal,2) + ""; - sXML += ""; - return sXML; + sXML += "" + RoundToString(dTotal,2) + ""; + sXML += ""; + return sXML; } @@ -3168,60 +3168,60 @@ double ReturnVerifiedVotingMagnitude(std::string sXML, bool bCreatedAfterSecurit Array GetJsonUnspentReport() { - // The purpose of this report is to list the details of unspent coins in the wallet, create a signed XML payload and then audit those coins as a third party - // Written on 5-28-2017 - R HALFORD - // We can use this as the basis for proving the total coin balance, and the current researcher magnitude in the voting system. + // The purpose of this report is to list the details of unspent coins in the wallet, create a signed XML payload and then audit those coins as a third party + // Written on 5-28-2017 - R HALFORD + // We can use this as the basis for proving the total coin balance, and the current researcher magnitude in the voting system. Array results; - //Retrieve the historical magnitude - if (!msPrimaryCPID.empty() && msPrimaryCPID != "INVESTOR") - { - StructCPID st1 = GetLifetimeCPID(msPrimaryCPID,"GetUnspentReport()"); - CBlockIndex* pHistorical = GetHistoricalMagnitude(msPrimaryCPID); - Object entry1; - entry1.push_back(Pair("Researcher Magnitude",pHistorical->nMagnitude)); - results.push_back(entry1); - - // Create the XML Magnitude Payload - if (pHistorical->nHeight > 1 && pHistorical->nMagnitude > 0) - { - std::string sBlockhash = pHistorical->GetBlockHash().GetHex(); - std::string sSignature = SignBlockWithCPID(msPrimaryCPID,pHistorical->GetBlockHash().GetHex()); - // Find the Magnitude from the last staked block, within the last 6 months, and ensure researcher has a valid current beacon (if the beacon is expired, the signature contain an error message) - - std::string sMagXML = "" + msPrimaryCPID + "" + RoundToString(pHistorical->nMagnitude,2) + "" + - "" + ToString(pHistorical->nHeight) + "" + sBlockhash + "" + sSignature + ""; - std::string sMagnitude = ExtractXML(sMagXML,"",""); - std::string sXmlSigned = ExtractXML(sMagXML,"",""); - std::string sXmlBlockHash = ExtractXML(sMagXML,"",""); - std::string sXmlCPID = ExtractXML(sMagXML,"",""); - Object entry; - entry.push_back(Pair("CPID Signature", sSignature)); - entry.push_back(Pair("Historical Magnitude Block #", pHistorical->nHeight)); - entry.push_back(Pair("Historical Blockhash", sBlockhash)); - // Prove the magnitude from a 3rd party standpoint: - if (!sXmlBlockHash.empty() && !sMagnitude.empty() && !sXmlSigned.empty()) - { - CBlockIndex* pblockindexMagnitude = mapBlockIndex[uint256(sXmlBlockHash)]; - if (pblockindexMagnitude) - { - bool fResult = VerifyCPIDSignature(sXmlCPID, sXmlBlockHash, sXmlSigned); - entry.push_back(Pair("Historical Magnitude",pblockindexMagnitude->nMagnitude)); - entry.push_back(Pair("Signature Valid",fResult)); - bool fAudited = (RoundFromString(RoundToString(pblockindexMagnitude->nMagnitude,2),0)==RoundFromString(sMagnitude,0) && fResult); - entry.push_back(Pair("Magnitude Audited",fAudited)); - results.push_back(entry); - - } - } + //Retrieve the historical magnitude + if (IsResearcher(msPrimaryCPID)) + { + StructCPID st1 = GetLifetimeCPID(msPrimaryCPID,"GetUnspentReport()"); + CBlockIndex* pHistorical = GetHistoricalMagnitude(msPrimaryCPID); + Object entry1; + entry1.push_back(Pair("Researcher Magnitude",pHistorical->nMagnitude)); + results.push_back(entry1); - - } - + // Create the XML Magnitude Payload + if (pHistorical->nHeight > 1 && pHistorical->nMagnitude > 0) + { + std::string sBlockhash = pHistorical->GetBlockHash().GetHex(); + std::string sSignature = SignBlockWithCPID(msPrimaryCPID,pHistorical->GetBlockHash().GetHex()); + // Find the Magnitude from the last staked block, within the last 6 months, and ensure researcher has a valid current beacon (if the beacon is expired, the signature contain an error message) + + std::string sMagXML = "" + msPrimaryCPID + "" + RoundToString(pHistorical->nMagnitude,2) + "" + + "" + ToString(pHistorical->nHeight) + "" + sBlockhash + "" + sSignature + ""; + std::string sMagnitude = ExtractXML(sMagXML,"",""); + std::string sXmlSigned = ExtractXML(sMagXML,"",""); + std::string sXmlBlockHash = ExtractXML(sMagXML,"",""); + std::string sXmlCPID = ExtractXML(sMagXML,"",""); + Object entry; + entry.push_back(Pair("CPID Signature", sSignature)); + entry.push_back(Pair("Historical Magnitude Block #", pHistorical->nHeight)); + entry.push_back(Pair("Historical Blockhash", sBlockhash)); + // Prove the magnitude from a 3rd party standpoint: + if (!sXmlBlockHash.empty() && !sMagnitude.empty() && !sXmlSigned.empty()) + { + CBlockIndex* pblockindexMagnitude = mapBlockIndex[uint256(sXmlBlockHash)]; + if (pblockindexMagnitude) + { + bool fResult = VerifyCPIDSignature(sXmlCPID, sXmlBlockHash, sXmlSigned); + entry.push_back(Pair("Historical Magnitude",pblockindexMagnitude->nMagnitude)); + entry.push_back(Pair("Signature Valid",fResult)); + bool fAudited = (RoundFromString(RoundToString(pblockindexMagnitude->nMagnitude,2),0)==RoundFromString(sMagnitude,0) && fResult); + entry.push_back(Pair("Magnitude Audited",fAudited)); + results.push_back(entry); - } + } + } + + + } + + + } - // Now we move on to proving the coins we own are ours + // Now we move on to proving the coins we own are ours vector vecOutputs; pwalletMain->AvailableCoins(vecOutputs, false, NULL, true); @@ -3784,7 +3784,7 @@ Array MagnitudeReportCSV(bool detail) StructCPID structMag = mvMagnitudes[(*ii).first]; if (structMag.initialized && structMag.cpid.length() > 2) { - if (structMag.cpid != "INVESTOR") + if (IsResearcher(structMag.cpid)) { outstanding = structMag.totalowed - structMag.payments; @@ -4199,7 +4199,7 @@ Value listitem(const Array& params, bool fHelp) if (structcpid.initialized) { - if (structcpid.cpid == GlobalCPUMiningCPID.cpid || structcpid.cpid=="INVESTOR" || structcpid.cpid=="investor") + if (structcpid.cpid == GlobalCPUMiningCPID.cpid || !IsResearcher(structcpid.cpid)) { if (structcpid.verifiedteam=="gridcoin") { @@ -4245,7 +4245,7 @@ Value listitem(const Array& params, bool fHelp) if ((GlobalCPUMiningCPID.cpid.length() > 3 && structcpid.cpid == GlobalCPUMiningCPID.cpid) - || structcpid.cpid=="INVESTOR" || GlobalCPUMiningCPID.cpid=="INVESTOR" || GlobalCPUMiningCPID.cpid.length()==0) + || !IsResearcher(structcpid.cpid) || !IsResearcher(GlobalCPUMiningCPID.cpid)) { Object entry; entry.push_back(Pair("Project",structcpid.projectname)); diff --git a/src/test/gridcoin_tests.cpp b/src/test/gridcoin_tests.cpp index 68f146e273..aeef2eceff 100755 --- a/src/test/gridcoin_tests.cpp +++ b/src/test/gridcoin_tests.cpp @@ -129,5 +129,27 @@ BOOST_AUTO_TEST_CASE(gridcoin_V8ShouldBeEnabledOnBlock312000InTestnet) fTestNet = was_testnet; } +BOOST_AUTO_TEST_CASE(gridcoin_InvestorsShouldNotBeResearchers) +{ + BOOST_CHECK(IsResearcher("INVESTOR") == false); + BOOST_CHECK(IsResearcher("investor") == false); +} + +BOOST_AUTO_TEST_CASE(gridcoin_EmptyCpidShouldNotBeResearcher) +{ + BOOST_CHECK(IsResearcher("") == false); +} + +BOOST_AUTO_TEST_CASE(gridcoin_IncompleteCpidShouldNotBeResearcher) +{ + BOOST_CHECK(IsResearcher("9c508a9e20f0415755db0ca27375c5") == false); +} + +BOOST_AUTO_TEST_CASE(gridcoin_ValidCpidShouldBeResearcher) +{ + BOOST_CHECK(IsResearcher("9c508a9e20f0415755db0ca27375c5fe") == true); +} + + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet.cpp b/src/wallet.cpp index aac1c108b2..a240198346 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -19,6 +19,7 @@ #include "util.h" #include #include +#include "main.h" using namespace std; @@ -1706,7 +1707,7 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue, CWalletTx& double MintLimiter(double PORDiff,int64_t RSA_WEIGHT,std::string cpid, int64_t locktime) { double MaxSubsidy = GetMaximumBoincSubsidy(locktime); - double por_min = (cpid != "INVESTOR") ? (MaxSubsidy/40) : 0; + double por_min = IsResearcher(cpid) ? (MaxSubsidy/40) : 0; if (RSA_WEIGHT >= 24999) return 0; //Dynamically determines the minimum GRC block subsidy required amount for current network conditions if (fTestNet && (PORDiff >=0 && PORDiff < 1)) return .00001; From 8529c3177e7b6c1a54afa6516646b2d86a2443ec Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 7 Nov 2017 21:58:12 +0100 Subject: [PATCH 117/166] Catch lexical cast errors and return 0 on float conversions. --- src/util.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index e94c901b01..1a7848ab23 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -1465,8 +1465,15 @@ std::string RoundToString(double d, int place) double RoundFromString(const std::string& s, int place) { - double num = boost::lexical_cast(s); - return Round(num, place); + try + { + double num = boost::lexical_cast(s); + return Round(num, place); + } + catch(const boost::bad_lexical_cast& e) + { + return 0; + } } bool Contains(const std::string& data, const std::string& instring) From 7e67576accec0cb971ab350f1705a0db13e3d915 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Tue, 7 Nov 2017 18:39:51 -0800 Subject: [PATCH 118/166] Remove reset of code related to RSA information no longer used in UI, and don't call MagnitudeReport for the overview string population --- src/main.cpp | 9 --------- src/main.h | 2 -- src/rpcblockchain.cpp | 8 -------- 3 files changed, 19 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5cea00e5ad..0e763a72ae 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -305,7 +305,6 @@ std::string msMiningErrors8; std::string msAttachmentGuid; std::string msMiningErrorsIncluded; std::string msMiningErrorsExcluded; -std::string msRSAOverview; std::string msNeuralResponse; std::string msHDDSerial; //When syncing, we grandfather block rejection rules up to this block, as rules became stricter over time and fields changed @@ -520,7 +519,6 @@ void GetGlobalStatus() GlobalStatusStruct.status = msMiningErrors; GlobalStatusStruct.poll = msPoll; GlobalStatusStruct.errors = MinerStatus.ReasonNotStaking + MinerStatus.Message + " " + msMiningErrors6 + " " + msMiningErrors7 + " " + msMiningErrors8; - GlobalStatusStruct.rsaOverview = msRSAOverview; // not displayed on overview page anymore. } return; } @@ -4383,13 +4381,6 @@ void GridcoinServices() AsyncNeuralRequest("explainmag",msPrimaryCPID,5); if (fDebug3) printf("Async explainmag sent for %s.",msPrimaryCPID.c_str()); } - // Run the RSA report for the overview page: - if (IsResearcher(msPrimaryCPID)) - { - if (fDebug3) printf("updating rsa\r\n"); - MagnitudeReport(msPrimaryCPID); - if (fDebug3) printf("updated rsa\r\n"); - } if (fDebug3) printf("\r\n MR Complete \r\n"); } catch (std::exception &e) diff --git a/src/main.h b/src/main.h index c92b6cb2b6..bd5306a3b4 100755 --- a/src/main.h +++ b/src/main.h @@ -206,7 +206,6 @@ extern std::string msAttachmentGuid; extern std::string msMiningErrorsIncluded; extern std::string msMiningErrorsExcluded; -extern std::string msRSAOverview; extern std::string msNeuralResponse; extern std::string msHDDSerial; extern bool mbBlocksDownloaded; @@ -227,7 +226,6 @@ struct globalStatusType std::string status; std::string poll; std::string errors; - std::string rsaOverview; }; extern globalStatusType GlobalStatusStruct; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 94f91a79fa..a4767d9d9a 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -2648,7 +2648,6 @@ Array MagnitudeReport(std::string cpid) results.push_back(c); double total_owed = 0; double magnitude_unit = GRCMagnitudeUnit(GetAdjustedTime()); - msRSAOverview = ""; if (!pindexBest) return results; try @@ -2697,13 +2696,6 @@ Array MagnitudeReport(std::string cpid) entry.push_back(Pair("Tx Count",(int)stCPID.Accuracy)); results.push_back(entry); - if (cpid==msPrimaryCPID && IsResearcher(msPrimaryCPID)) - { - msRSAOverview = "Exp PPD: " + RoundToString(dExpected14/14,0) - + ", Act PPD: " + RoundToString(structMag.payments/14,0) - + ", Fulf %: " + RoundToString(fulfilled,2) - + ", GRCMagUnit: " + RoundToString(magnitude_unit,4); - } } else { From a1a6c01d80224c1f6f8f0a164f0dc2895b0f0ca3 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Wed, 8 Nov 2017 13:05:13 +0100 Subject: [PATCH 119/166] Remove debugexplainmagnitude. It is only showing the magnitude from explainmagnitude. --- src/rpcblockchain.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index a4767d9d9a..7d66ce2dcd 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -55,7 +55,6 @@ extern Array SuperblockReport(std::string cpid); MiningCPID GetBoincBlockByIndex(CBlockIndex* pblockindex); extern double GetSuperblockMagnitudeByCPID(std::string data, std::string cpid); extern bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature); -double ExtractMagnitudeFromExplainMagnitude(); std::string GetQuorumHash(const std::string& data); double GetOutstandingAmountOwed(StructCPID &mag, std::string cpid, int64_t locktime, double& total_owed, double block_magnitude); bool ComputeNeuralNetworkSupermajorityHashes(); @@ -3963,13 +3962,6 @@ Value listitem(const Array& params, bool fHelp) results.push_back(entry); } - else if (sitem == "debugexplainmagnitude") - { - double dMag = ExtractMagnitudeFromExplainMagnitude(); - Object entry; - entry.push_back(Pair("Mag",dMag)); - results.push_back(entry); - } else if (sitem == "explainmagnitude") { Object entry; @@ -4260,7 +4252,6 @@ Value listitem(const Array& params, bool fHelp) entry.push_back(Pair("list cpids", "Displays information on cpids and the projects they are associated with")); entry.push_back(Pair("list currenttime", "Displays current unix time as well as UTC time and date")); entry.push_back(Pair("list detailmagnitudecsv", "Records more detailed magnitude report into a csv file")); - entry.push_back(Pair("list debugexplainmagnitude", "Displays more in detail your explainmagnitude from NN")); entry.push_back(Pair("list explainmagnitude ", "Displays information about your magnitude from NN; Optional true to force response")); entry.push_back(Pair("list lifetime", "Displays information on the life time of your cpid")); entry.push_back(Pair("list magnitude ", "Displays information on magnitude. cpid is optional.")); From c2c1d5e03e9c4e3b0c1b19b72e4c1bf7c67b988f Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Wed, 8 Nov 2017 13:20:51 -0800 Subject: [PATCH 120/166] update the snapshot url and use https instead of http --- src/upgrader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/upgrader.cpp b/src/upgrader.cpp index e8f2527009..7286fb3d66 100644 --- a/src/upgrader.cpp +++ b/src/upgrader.cpp @@ -38,7 +38,7 @@ static int cancelDownloader(void *p, std::string geturl() { - std::string url = "http://download.gridcoin.us/download/signed/"; + std::string url = "https://download.gridcoin.us/download/downloadstake/signed/"; // this will later be OS-dependent return url; } From e818a1b7324871f19a67d34b4fb7101d30971e32 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Wed, 8 Nov 2017 13:54:14 -0800 Subject: [PATCH 121/166] Disable Download Blocks menu except in windows. --- src/qt/bitcoingui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index f0f4035ba8..a3e13641c4 100755 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -764,7 +764,9 @@ void BitcoinGUI::createMenuBar() #endif /* defined(WIN32) */ qmAdvanced->addSeparator(); qmAdvanced->addAction(rebuildAction); +#ifdef WIN32 qmAdvanced->addAction(downloadAction); +#endif QMenu *help = appMenuBar->addMenu(tr("&Help")); help->addAction(openRPCConsoleAction); From 0e404255138dd5b7b5762b4ac389ae30f9abd7a8 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 9 Nov 2017 05:01:08 +0100 Subject: [PATCH 122/166] Add the neural tally time restriction back in. Windows wallet spent a lot of time tallying during syncing. --- src/main.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 0e763a72ae..0e8fec21fd 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -150,6 +150,7 @@ int64_t nLastPing = 0; int64_t nLastAskedForBlocks = 0; int64_t nBootup = 0; int64_t nLastLoadAdminMessages = 0; +int64_t nLastTalliedNeural = 0; int64_t nCPIDsLoaded = 0; int64_t nLastGRCtallied = 0; int64_t nLastCleaned = 0; @@ -5444,7 +5445,12 @@ StructCPID GetInitializedStructCPID2(const std::string& name, std::map 0) mvNeuralNetworkHash.clear(); if (mvNeuralVersion.size() > 0) mvNeuralVersion.clear(); From ceec98581e0efec0c49719710750e1304808f656 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 7 Nov 2017 15:39:53 +0100 Subject: [PATCH 123/166] Avoid concurrent stat syncing. --- contrib/Installer/boinc/boinc/Utilization.vb | 9 +-------- .../boinc/boinc/modPersistedDataSystem.vb | 16 ++++++---------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/contrib/Installer/boinc/boinc/Utilization.vb b/contrib/Installer/boinc/boinc/Utilization.vb index 099486ffe0..e5dfd765b5 100644 --- a/contrib/Installer/boinc/boinc/Utilization.vb +++ b/contrib/Installer/boinc/boinc/Utilization.vb @@ -152,12 +152,6 @@ Public Class Utilization Catch ex As Exception Log("New:" + ex.Message) End Try - Try - Dim sContract As String = GetMagnitudeContract() - If Len(sContract) = 0 Then bMagsDoneLoading = False - Catch ex As Exception - Log("contract err " + ex.Message) - End Try Catch ex As Exception Log("While loading clsUtilization : " + ex.Message) End Try @@ -501,8 +495,7 @@ Public Class Utilization Public Function SyncCPIDsWithDPORNodes(sData As String) As Double 'Write the Gridcoin CPIDs to the Persisted Data System Try - msSyncData = sData - Call SyncDPOR2() + Call SyncDPOR2(sData) Catch ex As Exception Log("Exception during SyncDpor2 : " + ex.Message) Return -2 diff --git a/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb b/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb index dcbbaeb422..04ae612622 100644 --- a/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb +++ b/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb @@ -413,8 +413,7 @@ Module modPersistedDataSystem End Try End Function - Public Sub SyncDPOR2() - If Math.Abs(DateDiff(DateInterval.Second, Now, mdLastSync)) > 60 * 10 Then bMagsDoneLoading = True + Public Sub SyncDPOR2(sData As String) If bMagsDoneLoading = False Then Log("Blocked call.") Exit Sub @@ -423,6 +422,10 @@ Module modPersistedDataSystem Log("Neural network is disabled.") Exit Sub End If + + msSyncData = sData + bMagsDoneLoading = False + Dim t As New Threading.Thread(AddressOf CompleteSync) t.Priority = Threading.ThreadPriority.BelowNormal t.Start() @@ -489,19 +492,12 @@ Module modPersistedDataSystem End Try End Function Public Sub CompleteSync() - If Math.Abs(DateDiff(DateInterval.Second, Now, mdLastSync)) > 60 * 10 Then bMagsDoneLoading = True - If bMagsDoneLoading = False Then Exit Sub - - mbForcefullySyncAllRac = True Log("Starting complete Neural Network Sync.") Try - EnsureNNDirExists() - msCurrentNeuralHash = "" - bMagsDoneLoading = False Try mlPercentComplete = 1 @@ -525,12 +521,12 @@ Module modPersistedDataSystem Log("Completesync:" + ex.Message) End Try - bMagsDoneLoading = True mdLastSync = Now mlPercentComplete = 0 '7-21-2015: Store historical magnitude so it can be charted StoreHistoricalMagnitude() bNeedsDgvRefreshed = True + bMagsDoneLoading = True End Sub Private Function GetMagByCPID(sCPID As String) As Row From 49134375af59d25bdc776876a42fc26bbd04479c Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 7 Nov 2017 21:22:46 +0100 Subject: [PATCH 124/166] Catch errors when opening files which have been deleted. --- contrib/Installer/boinc/boinc/modPersistedDataSystem.vb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb b/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb index 04ae612622..ffb7498905 100644 --- a/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb +++ b/contrib/Installer/boinc/boinc/modPersistedDataSystem.vb @@ -1064,7 +1064,9 @@ Module modPersistedDataSystem Dim fi As FileInfo Dim sPrefix = GetEntryPrefix(DataRow) For Each fi In fiArr - If Left(fi.Name, Len(sPrefix)) = sPrefix Then + If Left(fi.Name, Len(sPrefix)) <> sPrefix Then Continue For + + Try Using Stream As New System.IO.FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) Dim objReader As New System.IO.StreamReader(Stream) While objReader.EndOfStream = False @@ -1088,7 +1090,10 @@ Module modPersistedDataSystem End While objReader.Close() End Using - End If + Catch ex As IO.FileNotFoundException + Log("GetList: Error reading " + fi.FullName) + End Try + Next fi End SyncLock Return x From 81f6db938d9b9d08bca9fe1f33342422bce57fd3 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Thu, 9 Nov 2017 01:19:48 -0800 Subject: [PATCH 125/166] GridcoinServices Changes --- src/main.cpp | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0e763a72ae..693bff59c5 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4271,10 +4271,10 @@ void GridcoinServices() if(IsV9Enabled_Tally(nBestHeight)) { // Update quorum data. - if ((nBestHeight % 3) == 0) + if ((nBestHeight % 3) == 0 && !OutOfSyncByAge()) { - if(fDebug) printf("SVC: Updating Neural Quorum (v9 %%3) height %d\n",nBestHeight); - if(fDebug) printf("SVC: Updating Neural Supermajority (v9 %%3) height %d\n",nBestHeight); + if (fDebug) printf("SVC: Updating Neural Quorum (v9 %%3) height %d\n",nBestHeight); + if (fDebug) printf("SVC: Updating Neural Supermajority (v9 %%3) height %d\n",nBestHeight); ComputeNeuralNetworkSupermajorityHashes(); UpdateNeuralNetworkQuorumData(); } @@ -4282,7 +4282,7 @@ void GridcoinServices() // Tally research averages. if ((nBestHeight % TALLY_GRANULARITY) == 0) { - if(fDebug) printf("SVC: TallyNetworkAverages (v9 %%%d) height %d\n",TALLY_GRANULARITY,nBestHeight); + if (fDebug) printf("SVC: TallyNetworkAverages (v9 %%%d) height %d\n",TALLY_GRANULARITY,nBestHeight); TallyNetworkAverages_v9(); } } @@ -4292,46 +4292,43 @@ void GridcoinServices() bool bNeedSuperblock = (superblock_age > (GetSuperblockAgeSpacing(nBestHeight))); if ( nBestHeight % 3 == 0 && NeedASuperblock() ) bNeedSuperblock=true; - if (fDebug10) - { - printf (" MRSA %" PRId64 ", BH %d", superblock_age, nBestHeight); - } + if (fDebug10) printf(" MRSA %" PRId64 ", BH %d\n", superblock_age, nBestHeight); if (bNeedSuperblock) { - if ((nBestHeight % 3) == 0) + if ((nBestHeight % 3) == 0 && !OutOfSyncByAge()) { - if(fDebug) printf("SVC: Updating Neural Quorum (v3 A) height %d\n",nBestHeight); - if(fDebug) printf("SVC: Updating Neural Supermajority (v3 A) height %d\n",nBestHeight); + if (fDebug) printf("SVC: Updating Neural Quorum (v3 A) height %d\n",nBestHeight); + if (fDebug) printf("SVC: Updating Neural Supermajority (v3 A) height %d\n",nBestHeight); if (fDebug10) printf("#CNNSH# "); ComputeNeuralNetworkSupermajorityHashes(); UpdateNeuralNetworkQuorumData(); } if ((nBestHeight % 20) == 0) { - if(fDebug) printf("SVC: set off Tally (v3 B) height %d\n",nBestHeight); + if (fDebug) printf("SVC: set off Tally (v3 B) height %d\n",nBestHeight); if (fDebug10) printf("#TIB# "); bDoTally_retired = true; } } else { - // When superblock is not old, Tally every N mins: + // When superblock is not old, Tally every N blocks: int nTallyGranularity = fTestNet ? 60 : 20; if ((nBestHeight % nTallyGranularity) == 0) { - if(fDebug) printf("SVC: set off Tally (v3 C) height %d\n",nBestHeight); - if (fDebug3) printf("TIB1 "); - bDoTally_retired = true; - if (fDebug3) printf("CNNSH2 "); - if(fDebug) printf("SVC: Updating Neural Supermajority (v3 D) height %d\n",nBestHeight); - ComputeNeuralNetworkSupermajorityHashes(); + if (fDebug) printf("SVC: set off Tally (v3 C) height %d\n",nBestHeight); + if (fDebug3) printf("TIB1 "); + bDoTally_retired = true; } - if ((nBestHeight % 5)==0) + if ((nBestHeight % 5)==0 && !OutOfSyncByAge()) { - if(fDebug) printf("SVC: Updating Neural Quorum (v3 E) height %d\n",nBestHeight); - UpdateNeuralNetworkQuorumData(); + if (fDebug) printf("SVC: Updating Neural Quorum (v3 E) height %d\n",nBestHeight); + if (fDebug) printf("SVC: Updating Neural Supermajority (v3 D) height %d\n",nBestHeight); + if (fDebug3) printf("CNNSH2 "); + ComputeNeuralNetworkSupermajorityHashes(); + UpdateNeuralNetworkQuorumData(); } } } @@ -4343,7 +4340,7 @@ void GridcoinServices() //Dont perform the following functions if out of sync - if (pindexBest->nHeight < nGrandfather && OutOfSyncByAge()) + if (pindexBest->nHeight < nGrandfather || OutOfSyncByAge()) return; if (fDebug) printf(" {SVC} "); From 157b59484eeb61998c2879273f0c60c21193c90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sun, 22 Oct 2017 14:09:10 +0200 Subject: [PATCH 126/166] Don't rely on git-describe --- share/genbuild.sh | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/share/genbuild.sh b/share/genbuild.sh index 35d43eb35f..73d5cd883a 100644 --- a/share/genbuild.sh +++ b/share/genbuild.sh @@ -15,9 +15,6 @@ if [ -e "$(which git)" ]; then # clean 'dirty' status of touched files that haven't been modified git diff >/dev/null 2>/dev/null - # get a string like "v0.6.0-66-g59887e8-dirty" - DESC="$(git describe --dirty 2>/dev/null)" - # get only commit hash, but format like describe DESCHASH="$(git rev-parse --short=9 HEAD 2>/dev/null)" @@ -31,19 +28,14 @@ if [ -e "$(which git)" ]; then TIME="$(git log -n 1 --format="%ci")" fi -if [ -n "$DESC" ]; then - NEWINFO="#define BUILD_DESC \"v$DESC\"" +if [ -n "$DESCHASH" ]; then + NEWINFO="#define BUILD_DESCHASH \"$DESCHASH\"" else NEWINFO="// No build information available" fi -if [ -n "$DESCHASH" ]; then - NEWINFO="$NEWINFO -#define BUILD_DESCHASH \"$DESCHASH\"" -else - NEWINFO="$NEWINFO -// No build information available" -fi +NEWINFO="$NEWINFO +//placeholder" # only update build.h if necessary if [ "$INFO" != "$NEWINFO" ]; then From a0830a99bbfc430b275222889ec923af56753b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Thu, 9 Nov 2017 10:46:09 +0100 Subject: [PATCH 127/166] Bump client BUILD number. --- src/clientversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clientversion.h b/src/clientversion.h index b8d5333af3..a3b6f06370 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 3 #define CLIENT_VERSION_MINOR 6 #define CLIENT_VERSION_REVISION 3 -#define CLIENT_VERSION_BUILD 0 +#define CLIENT_VERSION_BUILD 17 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! From f091def597a47e4e8fe35e6f6c857ddf8bd297d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Thu, 9 Nov 2017 10:53:26 +0100 Subject: [PATCH 128/166] Changed CLIENT_NAME to Halford. --- src/version.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.cpp b/src/version.cpp index 4f2531f2e6..07e2992410 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -8,7 +8,7 @@ // Name of client reported in the 'version' message. Report the same name // for both bitcoind and bitcoin-qt, to make it harder for attackers to // target servers or GUI users specifically. -const std::string CLIENT_NAME("Nakamoto"); +const std::string CLIENT_NAME("Halford"); // Client version number #define CLIENT_VERSION_SUFFIX "" From 34056cc7285985bc1e0ddf0689e07d187a03f213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Thu, 9 Nov 2017 11:29:17 +0100 Subject: [PATCH 129/166] Prevent development builds from staking and sending transactions outside testnet. --- src/init.cpp | 10 ++++++++++ src/miner.cpp | 7 +++++++ src/util.cpp | 1 + src/util.h | 1 + src/wallet.cpp | 5 +++++ 5 files changed, 24 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 906eb1594a..b4c7837e42 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -624,6 +624,16 @@ bool AppInit2(ThreadHandlerPtr threads) printf("Used data directory %s\n", strDataDir.c_str()); std::ostringstream strErrors; + fDevbuildCripple = false; + if((CLIENT_VERSION_BUILD != 0) && !fTestNet) + { + fDevbuildCripple = true; + printf("WARNING: Running development version outside of testnet!\n" + "Staking and sending transactions will be disabled.\n"); + if( (GetArg("-devbuild", "") == "override") && fDebug ) + fDevbuildCripple = false; + } + if (fDaemon) fprintf(stdout, "Gridcoin server starting\n"); diff --git a/src/miner.cpp b/src/miner.cpp index bfe6a876bd..7aa947a564 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -787,6 +787,13 @@ bool IsMiningAllowed(CWallet *pwallet) status=false; } + if(fDevbuildCripple) + { + LOCK(MinerStatus.lock); + MinerStatus.ReasonNotStaking+="Testnet-only version; "; + status=false; + } + if (!bNetAveragesLoaded) { LOCK(MinerStatus.lock); diff --git a/src/util.cpp b/src/util.cpp index 1a7848ab23..ee2700b4f2 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -84,6 +84,7 @@ CMedianFilter vTimeOffsets(200,0); bool fReopenDebugLog = false; std::string GetNeuralVersion(); +bool fDevbuildCripple; int64_t IsNeural(); diff --git a/src/util.h b/src/util.h index e85891e82b..4b1f7b49fb 100755 --- a/src/util.h +++ b/src/util.h @@ -111,6 +111,7 @@ extern bool fTestNet; extern bool fNoListen; extern bool fLogTimestamps; extern bool fReopenDebugLog; +extern bool fDevbuildCripple; void RandAddSeed(); void RandAddSeedPerfmon(); diff --git a/src/wallet.cpp b/src/wallet.cpp index a240198346..3ceec6c1b6 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1803,6 +1803,11 @@ void NetworkTimer() // Call after CreateTransaction unless you want to abort bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) { + if(fDevbuildCripple) + { + error("CommitTransaction(): Development build restrictions in effect"); + return false; + } { LOCK2(cs_main, cs_wallet); if (fDebug) printf("CommitTransaction:\n%s", wtxNew.ToString().c_str()); From 13c4e18502f83cac060a83fc1aa9ad0928d0f0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Thu, 9 Nov 2017 13:26:53 +0100 Subject: [PATCH 130/166] Corrected neural supermaiority update. Check superblock always in v9. Neural sync every 10 blocks (15 min) instead of 3 in v9. --- src/main.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a83c40eb8d..79d9f31894 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3194,7 +3194,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo double popularity = 0; std::string consensus_hash = GetNeuralNetworkSupermajorityHash(popularity); // Only reject superblock when it is new And when QuorumHash of Block != the Popular Quorum Hash: - if (IsLockTimeWithinMinutes(GetBlockTime(),15) && !fColdBoot) + if ((IsLockTimeWithinMinutes(GetBlockTime(),15) || nVersion>=9) && !fColdBoot) { // Let this take effect together with stakev8 if (nVersion>=8) @@ -4272,11 +4272,15 @@ void GridcoinServices() if(IsV9Enabled_Tally(nBestHeight)) { // Update quorum data. - if ((nBestHeight % 3) == 0 && !OutOfSyncByAge()) + if ((nBestHeight % 3) == 0) { - if (fDebug) printf("SVC: Updating Neural Quorum (v9 %%3) height %d\n",nBestHeight); if (fDebug) printf("SVC: Updating Neural Supermajority (v9 %%3) height %d\n",nBestHeight); ComputeNeuralNetworkSupermajorityHashes(); + } + // Update quorum data. + if ((nBestHeight % 10) == 0 && !OutOfSyncByAge() && NeedASuperblock()) + { + if (fDebug) printf("SVC: Updating Neural Quorum (v9 M) height %d\n",nBestHeight); UpdateNeuralNetworkQuorumData(); } @@ -4297,12 +4301,15 @@ void GridcoinServices() if (bNeedSuperblock) { + if ((nBestHeight % 3) == 0) + { + if (fDebug) printf("SVC: Updating Neural Supermajority (v3 A) height %d\n",nBestHeight); + ComputeNeuralNetworkSupermajorityHashes(); + } if ((nBestHeight % 3) == 0 && !OutOfSyncByAge()) { if (fDebug) printf("SVC: Updating Neural Quorum (v3 A) height %d\n",nBestHeight); - if (fDebug) printf("SVC: Updating Neural Supermajority (v3 A) height %d\n",nBestHeight); if (fDebug10) printf("#CNNSH# "); - ComputeNeuralNetworkSupermajorityHashes(); UpdateNeuralNetworkQuorumData(); } if ((nBestHeight % 20) == 0) @@ -4323,12 +4330,15 @@ void GridcoinServices() bDoTally_retired = true; } + if ((nBestHeight % 5)==0) + { + if (fDebug) printf("SVC: Updating Neural Supermajority (v3 D) height %d\n",nBestHeight); + UpdateNeuralNetworkQuorumData(); + } if ((nBestHeight % 5)==0 && !OutOfSyncByAge()) { if (fDebug) printf("SVC: Updating Neural Quorum (v3 E) height %d\n",nBestHeight); - if (fDebug) printf("SVC: Updating Neural Supermajority (v3 D) height %d\n",nBestHeight); if (fDebug3) printf("CNNSH2 "); - ComputeNeuralNetworkSupermajorityHashes(); UpdateNeuralNetworkQuorumData(); } } From cfda6b86f50d6bcca1ed7711bc6651e6e4c72860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Fri, 10 Nov 2017 14:56:49 +0100 Subject: [PATCH 131/166] Wrong service function called. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 79d9f31894..237551cd43 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4333,7 +4333,7 @@ void GridcoinServices() if ((nBestHeight % 5)==0) { if (fDebug) printf("SVC: Updating Neural Supermajority (v3 D) height %d\n",nBestHeight); - UpdateNeuralNetworkQuorumData(); + ComputeNeuralNetworkSupermajorityHashes(); } if ((nBestHeight % 5)==0 && !OutOfSyncByAge()) { From 24f0fb4a5326f7c03f607e78c032d0d5b16fac8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Thu, 9 Nov 2017 12:11:16 +0100 Subject: [PATCH 132/166] Add better command to send alerts. --- src/bitcoinrpc.cpp | 5 ++++ src/bitcoinrpc.h | 1 + src/rpcnet.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 369e6997f3..c258fd9796 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -307,6 +307,7 @@ static const CRPCCommand vRPCCommands[] = { "sendalert", &sendalert, false, false}, { "reorganize", &rpc_reorganize, false, false}, { "getblockstats", &rpc_getblockstats, false, false}, + { "sendalert2", &sendalert2, false, false}, }; CRPCTable::CRPCTable() @@ -1232,6 +1233,10 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 5) ConvertTo(params[5]); if (strMethod == "sendalert" && n > 6) ConvertTo(params[6]); + if (strMethod == "sendalert2" && n > 5) ConvertTo(params[5]); + if (strMethod == "sendalert2" && n > 1) ConvertTo(params[1]); + if (strMethod == "sendalert2" && n > 4) ConvertTo(params[4]); + if (strMethod == "sendmany" && n > 1) ConvertTo(params[1]); if (strMethod == "sendmany" && n > 2) ConvertTo(params[2]); if (strMethod == "reservebalance" && n > 0) ConvertTo(params[0]); diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 532e8b8c94..6f0a1d5acf 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -230,5 +230,6 @@ extern json_spirit::Value rpc_reorganize(const json_spirit::Array& params, bool // Brod extern json_spirit::Value rpc_getblockstats(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value sendalert2(const json_spirit::Array& params, bool fHelp); #endif diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 826f7fd3de..97afee86e6 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -407,3 +407,64 @@ Value sendalert(const Array& params, bool fHelp) result.push_back(Pair("nCancel", alert.nCancel)); return result; } + +Value sendalert2(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 7) + throw runtime_error( + // 0 1 2 3 4 5 6 + "sendalert \n" + " is the alert text message\n" + " is hex string of alert master private key\n" + " comma separated list of versions warning applies to\n" + " integer, >1000->visible\n" + " is the unique alert number\n" + " comma separated ids of alerts to cancel\n" + " alert expiration in days\n" + "Returns true or false."); + + CAlert alert; + CKey key; + + alert.strStatusBar = params[6].get_str(); + alert.nMinVer = PROTOCOL_VERSION; + alert.nMaxVer = PROTOCOL_VERSION; + alert.nPriority = params[5].get_int(); + alert.nID = params[1].get_int(); + alert.nVersion = PROTOCOL_VERSION; + alert.nRelayUntil = alert.nExpiration = GetAdjustedTime() + 24*60*60*params[4].get_int(); + + std::vector split_subver = split(params[2].get_str(), ","); + alert.setSubVer.insert(split_subver.begin(),split_subver.end()); + + std::vector split_cancel = split(params[3].get_str(), ","); + for(std::string &s : split_cancel) + { + int aver = RoundFromString(s, 0); + alert.setCancel.insert(aver); + } + + CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION); + sMsg << (CUnsignedAlert)alert; + alert.vchMsg = vector(sMsg.begin(), sMsg.end()); + + vector vchPrivKey = ParseHex(params[0].get_str()); + key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash + if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig)) + throw runtime_error( + "Unable to sign alert, check private key?\n"); + if(!alert.ProcessAlert()) + throw runtime_error( + "Failed to process alert.\n"); + // Relay alert + { + LOCK(cs_vNodes); + for (auto const& pnode : vNodes) + alert.RelayTo(pnode); + } + + Object result; + result.push_back(Pair("Content", alert.ToString())); + result.push_back(Pair("Success", true)); + return result; +} From e9dc1aebf4b6c87dfcf9a33489cdf5dd07745101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Fri, 10 Nov 2017 15:13:27 +0100 Subject: [PATCH 133/166] Do not rely on counting votes in Services. Count them when creating or validating a superblock (v9). --- src/main.cpp | 16 ++++++++++------ src/main.h | 1 + src/miner.cpp | 7 +++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 237551cd43..64389abb26 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -111,7 +111,6 @@ extern double GetOutstandingAmountOwed(StructCPID &mag, std::string cpid, int64_ extern double GetOwedAmount(std::string cpid); -extern bool ComputeNeuralNetworkSupermajorityHashes(); extern void DeleteCache(std::string section, std::string keyname); extern void ClearCache(std::string section); @@ -3181,11 +3180,16 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo if (bb.superblock.length() > 20) { - // Prevent duplicate superblocks - if(nVersion >= 9 && !NeedASuperblock()) - return error(("ConnectBlock: SuperBlock rcvd, but not Needed (too early)")); - - if ((pindex->nHeight > nGrandfather && !fReorganizing) || pindex->nVersion >= 9 ) + if(nVersion >= 9) + { + // break away from block timing + if (fDebug) printf("ConnectBlock: Updating Neural Supermajority (v9 CB) height %d\n",pindex->nHeight); ComputeNeuralNetworkSupermajorityHashes(); + // Prevent duplicate superblocks + if(nVersion >= 9 && !NeedASuperblock()) + return error(("ConnectBlock: SuperBlock rcvd, but not Needed (too early)")); + } + + if ((pindex->nHeight > nGrandfather && !fReorganizing) || nVersion >= 9 ) { // 12-20-2015 : Add support for Binary Superblocks std::string superblock = UnpackBinarySuperblock(bb.superblock); diff --git a/src/main.h b/src/main.h index bd5306a3b4..b07adcff40 100755 --- a/src/main.h +++ b/src/main.h @@ -301,6 +301,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); StructCPID GetInitializedStructCPID2(const std::string& name, std::map& vRef); bool IsResearcher(const std::string& cpid); +extern bool ComputeNeuralNetworkSupermajorityHashes(); /** Position on disk for a particular transaction. */ class CDiskTxPos diff --git a/src/miner.cpp b/src/miner.cpp index bfe6a876bd..123277eb67 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -673,6 +673,13 @@ int AddNeuralContractOrVote(const CBlock &blocknew, MiningCPID &bb) if(!IsNeuralNodeParticipant(bb.GRCAddress, blocknew.nTime)) return printf("AddNeuralContractOrVote: Not Participating\n"); + if(blocknew.nVersion >= 9) + { + // break away from block timing + if (fDebug) printf("AddNeuralContractOrVote: Updating Neural Supermajority (v9 M) height %d\n",nBestHeight); + ComputeNeuralNetworkSupermajorityHashes(); + } + if(!NeedASuperblock()) return printf("AddNeuralContractOrVote: not Needed\n"); From 32a07cd42f3456237f84e97a948397091dd89824 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 11 Nov 2017 03:41:05 +0100 Subject: [PATCH 134/166] Revert "Add the neural tally time restriction back in." This reverts commit 0e404255138dd5b7b5762b4ac389ae30f9abd7a8. The tally is not what was causing the CPU spike, the VB communication was. We still want to tally while syncing to be able to verify superblocks. --- src/main.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a83c40eb8d..693bff59c5 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -150,7 +150,6 @@ int64_t nLastPing = 0; int64_t nLastAskedForBlocks = 0; int64_t nBootup = 0; int64_t nLastLoadAdminMessages = 0; -int64_t nLastTalliedNeural = 0; int64_t nCPIDsLoaded = 0; int64_t nLastGRCtallied = 0; int64_t nLastCleaned = 0; @@ -5442,12 +5441,7 @@ StructCPID GetInitializedStructCPID2(const std::string& name, std::map 0) mvNeuralNetworkHash.clear(); if (mvNeuralVersion.size() > 0) mvNeuralVersion.clear(); From 84a41344600d45acd8048768229cfb129d46413e Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 11 Nov 2017 04:10:03 +0100 Subject: [PATCH 135/166] Remove forwar declaration. --- src/init.cpp | 1 - src/rpcblockchain.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 906eb1594a..0de64594fa 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -23,7 +23,6 @@ bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); StructCPID GetStructCPID(); -bool ComputeNeuralNetworkSupermajorityHashes(); void BusyWaitForTally_retired(); void TallyNetworkAverages_v9(); extern void ThreadAppInit2(void* parg); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 7d66ce2dcd..0706d192a1 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -57,7 +57,6 @@ extern double GetSuperblockMagnitudeByCPID(std::string data, std::string cpid); extern bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature); std::string GetQuorumHash(const std::string& data); double GetOutstandingAmountOwed(StructCPID &mag, std::string cpid, int64_t locktime, double& total_owed, double block_magnitude); -bool ComputeNeuralNetworkSupermajorityHashes(); bool UpdateNeuralNetworkQuorumData(); extern Array LifetimeReport(std::string cpid); extern std::string AddContract(std::string sType, std::string sName, std::string sContract); From 2f5149b99a8ae5fe3f197ee4594d416a1f7db552 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 12 Nov 2017 04:27:49 +0100 Subject: [PATCH 136/166] Fix RPC handler thread getting stuck on shutdown. --- src/bitcoinrpc.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index c258fd9796..60d17dee3e 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -24,6 +24,8 @@ #include #include +#include + #define printf OutputDebugStringF using namespace std; @@ -669,12 +671,14 @@ class AcceptedConnectionImpl : public AcceptedConnection void StopRPCThreads() { + printf("Stop RPC IO service\n"); if(!rpc_io_service) + { + printf("RPC IO server not started\n"); return; + } rpc_io_service->stop(); - delete rpc_io_service; - rpc_io_service = NULL; } void ThreadRPCServer(void* parg) @@ -695,10 +699,6 @@ void ThreadRPCServer(void* parg) printf("ThreadRPCServer exited (interrupt)\r\n"); return; } - catch (...) - { - PrintException(NULL, "ThreadRPCServer()"); - } printf("ThreadRPCServer exited\n"); } @@ -902,6 +902,9 @@ void ThreadRPCServer2(void* parg) while (!fShutdown) rpc_io_service->run_one(); + + delete rpc_io_service; + rpc_io_service = NULL; StopRequests(); } From 3810466603ad7d3f40452cacf3f845f220e0cf6c Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 12 Nov 2017 20:24:48 +0100 Subject: [PATCH 137/166] Bump V9 trigger to 399000 on testnet. --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index b07adcff40..775878884b 100755 --- a/src/main.h +++ b/src/main.h @@ -99,7 +99,7 @@ inline uint32_t IsV8Enabled(int nHeight) inline uint32_t IsV9Enabled(int nHeight) { return fTestNet - ? nHeight >= 392570 + ? nHeight >= 399000 : nHeight >= 2000000; } From 31b5658480c18f10124cac297f0921fcb37e0479 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 16 Nov 2017 04:57:26 +0100 Subject: [PATCH 138/166] Change comparison to assignment when composing HTML string. --- src/qt/transactiondesc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 239c43c041..51fb778b2b 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -301,7 +301,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) strHTML += "
    "; } - strHTML == "

    " + tr("Gridcoin generated coins must mature 110 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
    "; + strHTML = "

    " + tr("Gridcoin generated coins must mature 110 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
    "; } else if (!wtx.hashBoinc.empty()) From 944e26e7f8c06e8feb89645f9689200af0d55d91 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 16 Nov 2017 08:31:18 +0100 Subject: [PATCH 139/166] Fix strHTML properly this time. --- src/qt/transactiondesc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 51fb778b2b..e85c37da6b 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -301,7 +301,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) strHTML += "
    "; } - strHTML = "

    " + tr("Gridcoin generated coins must mature 110 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
    "; + strHTML += "

    " + tr("Gridcoin generated coins must mature 110 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
    "; } else if (!wtx.hashBoinc.empty()) From d03f09ab972e9358336009da8fb061f248a8ea8c Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 24 Nov 2017 18:20:30 +0100 Subject: [PATCH 140/166] Fix Gridcoin spelling errors. This closes #742. --- src/qt/locale/bitcoin_pt_PT.ts | 2 +- src/qt/locale/bitcoin_ru.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 9fe3135436..40dd84fa2f 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -2609,7 +2609,7 @@ Isto significa que uma taxa de pelo menos %2 é necesária. Gridcoin generated coins must mature 110 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. - As moedas gerados pelo Gricoin devem maturar durante 110 blocos antes de poderem ser gastas. Quando gerou este bloco, ele foi transmitido à rede para ser adicionado à cadeia de blocos. Se falhar a entrada na cadeia, o seu estado será alterado para "não aceite" e não será' possivel de usar. Isto pode acontecer ocasionalmente se outro módulo gerar um bloxo com segundos de diferença do seu. + As moedas gerados pelo Gridcoin devem maturar durante 110 blocos antes de poderem ser gastas. Quando gerou este bloco, ele foi transmitido à rede para ser adicionado à cadeia de blocos. Se falhar a entrada na cadeia, o seu estado será alterado para "não aceite" e não será' possivel de usar. Isto pode acontecer ocasionalmente se outro módulo gerar um bloxo com segundos de diferença do seu. diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 2e6d3a1277..9b3e88c47e 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -642,7 +642,7 @@ This product includes software developed by the OpenSSL Project for use in the O %1 active connection(s) to Gridcoin network - %1 Активные соединения в сети Gricoin + %1 Активные соединения в сети Gridcoin From 70f3e0d7dd4aa0439f96c78fa1f6f065af757666 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 25 Nov 2017 06:14:35 +0100 Subject: [PATCH 141/166] Fix invalid icon path. --- share/qt/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qt/Info.plist b/share/qt/Info.plist index f60f0453a7..206c879590 100644 --- a/share/qt/Info.plist +++ b/share/qt/Info.plist @@ -3,7 +3,7 @@ CFBundleIconFile - bitcoin.icns + gridcoin.icns CFBundlePackageType APPL CFBundleGetInfoString From 51918828b7af1c79af46abfb5b11645138c17737 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 7 Dec 2017 10:28:47 +0100 Subject: [PATCH 142/166] Simplify fork reorganize. Remove the incremental steps and tally after reorganize. Also tally every N block as in GridcoinServices. --- src/main.cpp | 65 +++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f9252796b9..343fa07e75 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3388,7 +3388,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) printf("REORGANIZE: Disconnect %" PRIszu " blocks; %s..%s\n", vDisconnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexBest->GetBlockHash().ToString().substr(0,20).c_str()); printf("REORGANIZE: Connect %" PRIszu " blocks; %s..%s\n", vConnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->GetBlockHash().ToString().substr(0,20).c_str()); - if (vDisconnect.size() > 0) + if (vDisconnect.empty() == false) { //Block was disconnected - User is Re-eligibile for staking @@ -3401,7 +3401,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) } nLastBlockSolved = 0; } - printf("REORGANIZE Disc Size %f",(double)vDisconnect.size()); + printf("REORGANIZE Disc Size %" PRIszu, vDisconnect.size()); // Disconnect shorter branch list vResurrect; @@ -3449,13 +3449,6 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) // Queue memory transactions to delete for( const CTransaction& tx : block.vtx ) vDelete.push_back(tx); - - if (!IsResearchAgeEnabled(pindex->nHeight)) - { - //MiningCPID bb = GetInitializedMiningCPID(pindex->GetBlockHash().GetHex(), mvBlockIndex); - //bb = DeserializeBoincBlock(block.vtx[0].hashBoinc); - //mvBlockIndex[pindex->GetBlockHash().GetHex()] = bb; - } } if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) @@ -3581,42 +3574,34 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) { // the first block in the new chain that will cause it to become the new best chain CBlockIndex *pindexIntermediate = pindexNew; + // list of blocks that need to be connected afterwards std::vector vpindexSecondary; printf("\r\n**Reorganize**"); - //10-6-2015 Make Reorganize work more gracefully - try up to 5 times to reorganize, each with an intermediate further back - for (int iRegression = 0; iRegression < 5; iRegression++) + // Reorganize is costly in terms of db load, as it works in a single db transaction. + // Try to limit how much needs to be done inside + while (pindexIntermediate->pprev && pindexIntermediate->pprev->nChainTrust > pindexBest->nChainTrust) { - int rollback = iRegression * 100; - - // Reorganize is costly in terms of db load, as it works in a single db transaction. - // Try to limit how much needs to be done inside - int rolled_back = 1; - while (pindexIntermediate->pprev && pindexIntermediate->pprev->nChainTrust > pindexBest->nChainTrust && rolled_back < rollback) - { - vpindexSecondary.push_back(pindexIntermediate); - pindexIntermediate = pindexIntermediate->pprev; - if (pindexIntermediate==pindexGenesisBlock) break; - rolled_back++; - } - - if (!vpindexSecondary.empty()) - printf("\r\nReorganizing Attempt #%f, regression to block #%f \r\n",(double)iRegression+1,(double)pindexIntermediate->nHeight); + vpindexSecondary.push_back(pindexIntermediate); + pindexIntermediate = pindexIntermediate->pprev; + } + if (!vpindexSecondary.empty()) printf("Postponing %" PRIszu " reconnects\n", vpindexSecondary.size()); - if (iRegression==4 && !Reorganize(txdb, pindexIntermediate)) - { - printf("Failed to Reorganize during Attempt #%f \r\n",(double)iRegression+1); - txdb.TxnAbort(); - InvalidChainFound(pindexNew); - printf("\r\nReorg tally\r\n"); - BusyWaitForTally_retired(); - TallyNetworkAverages_v9(); - return error("SetBestChain() : Reorganize failed"); - } + + if (!Reorganize(txdb, pindexIntermediate)) + { + printf("Reorganize failed"); + txdb.TxnAbort(); + InvalidChainFound(pindexNew); + return error("SetBestChain() : Reorganize failed"); } + // Retally after reorganize to sync up amounts owed. + BusyWaitForTally_retired(); + TallyNetworkAverages_v9(); + // Switch to new best branch // Connect further blocks for (auto &pindex : boost::adaptors::reverse(vpindexSecondary)) @@ -3631,9 +3616,17 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) printf("SetBestChain() : TxnBegin 2 failed\n"); break; } + // errors now are not fatal, we still did a reorganisation to a new chain in a valid way if (!block.SetBestChainInner(txdb, pindex, true)) break; + + // Retally every N blocks. + if ((pindex->nHeight % TALLY_GRANULARITY) == 0) + { + BusyWaitForTally_retired(); + TallyNetworkAverages_v9(); + } } } From 5985396f2839378bddc174ae9896adf816332764 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 7 Dec 2017 10:45:32 +0100 Subject: [PATCH 143/166] Move GridcoinServices to SetBestChain in V9. Also remove the tallying while connecting blocks after reorganize. The PoR/PoS checks are skipped anyway. --- src/main.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 343fa07e75..e4a572e9e5 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3598,10 +3598,6 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) return error("SetBestChain() : Reorganize failed"); } - // Retally after reorganize to sync up amounts owed. - BusyWaitForTally_retired(); - TallyNetworkAverages_v9(); - // Switch to new best branch // Connect further blocks for (auto &pindex : boost::adaptors::reverse(vpindexSecondary)) @@ -3620,14 +3616,11 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) // errors now are not fatal, we still did a reorganisation to a new chain in a valid way if (!block.SetBestChainInner(txdb, pindex, true)) break; - - // Retally every N blocks. - if ((pindex->nHeight % TALLY_GRANULARITY) == 0) - { - BusyWaitForTally_retired(); - TallyNetworkAverages_v9(); - } } + + // Retally after reorganize to sync up amounts owed. + BusyWaitForTally_retired(); + TallyNetworkAverages_v9(); } // Update best block in wallet (so we can detect restored wallets) @@ -3685,6 +3678,11 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) boost::thread t(runCommand, strCmd); // thread runs free } + // Perform Gridcoin services now that w have a new head. + // Remove V9 checks after the V9 switch. + if(IsV9Enabled(nBestHeight)) + GridcoinServices(); + return true; } @@ -4691,7 +4689,11 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock, bool generated_by_me) } printf("{PB}: ACC; \r\n"); - GridcoinServices(); + + // Compatiblity while V8 is in use. Can be removed after the V9 switch. + if(IsV9Enabled(pindexBest->nHeight) == false) + GridcoinServices(); + return true; } From 6875db3d52d39ae2f26f0cab202999ff2dce3aae Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 7 Dec 2017 10:49:28 +0100 Subject: [PATCH 144/166] Remove version upgrade check in SetBestChain. --- src/main.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e4a572e9e5..ac5679f94d 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3652,26 +3652,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) else printf("{SBC} new best=%s height=%d ; ",hashBestChain.ToString().c_str(), nBestHeight); - // Check the version of the last 100 blocks to see if we need to upgrade: - if (!fIsInitialDownload) - { - int nUpgraded = 0; - const CBlockIndex* pindex = pindexBest; - for (int i = 0; i < 100 && pindex != NULL; i++) - { - if (pindex->nVersion > CBlock::CURRENT_VERSION) - ++nUpgraded; - pindex = pindex->pprev; - } - if (nUpgraded > 0) - printf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION); - if (nUpgraded > 100/2) - // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: - strMiscWarning = _("Warning: This version is obsolete, upgrade required!"); - } - std::string strCmd = GetArg("-blocknotify", ""); - if (!fIsInitialDownload && !strCmd.empty()) { boost::replace_all(strCmd, "%s", hashBestChain.GetHex()); From ea047e58a1334054b20f9ccbb6054f0650641539 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 10 Dec 2017 09:19:38 +0100 Subject: [PATCH 145/166] Recalculate amounts paid after switching to a new chain. --- src/main.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ac5679f94d..d4e64f3a88 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -2186,7 +2186,7 @@ bool CheckProofOfResearch( bb.ResearchSubsidy, OUT_POR, bb.cpid.c_str() ); BusyWaitForTally_retired(); - StructCPID st1 = GetLifetimeCPID(bb.cpid,"CheckProofOfResearch()"); + GetLifetimeCPID(bb.cpid,"CheckProofOfResearch()"); nCalculatedResearch = GetProofOfStakeReward(nCoinAge, nFees, bb.cpid, true, 2, block.nTime, pindexBest, "checkblock_researcher_doublecheck", OUT_POR, OUT_INTEREST, dAccrualAge, dMagnitudeUnit, dAvgMagnitude); } @@ -3600,6 +3600,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) // Switch to new best branch // Connect further blocks + std::set connected_cpids; for (auto &pindex : boost::adaptors::reverse(vpindexSecondary)) { CBlock block; @@ -3616,11 +3617,18 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) // errors now are not fatal, we still did a reorganisation to a new chain in a valid way if (!block.SetBestChainInner(txdb, pindex, true)) break; + + if(pindex->IsUserCPID()) + connected_cpids.emplace(pindex->cpid); } // Retally after reorganize to sync up amounts owed. BusyWaitForTally_retired(); TallyNetworkAverages_v9(); + + // Recalculate amounts paid. + for(const auto& cpid : connected_cpids) + GetLifetimeCPID(cpid.GetHex(), "SetBestChain()"); } // Update best block in wallet (so we can detect restored wallets) @@ -5738,18 +5746,13 @@ bool TallyResearchAverages_v9() bNetAveragesLoaded = true; return true; } - catch (bad_alloc ba) + catch (const std::bad_alloc& ba) { printf("Bad Alloc while tallying network averages. [1]\r\n"); bNetAveragesLoaded=true; } - catch(...) - { - printf("Error while tallying network averages. [1]\r\n"); - bNetAveragesLoaded=true; - } - if (fDebug3) printf("NA loaded in %f",(double)GetTimeMillis()-nStart); + if (fDebug3) printf("NA loaded in %" PRId64, GetTimeMillis() - nStart); bNetAveragesLoaded=true; return false; From 5bbae3041b7166f006e14471943694ef31076af0 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 10 Dec 2017 09:51:58 +0100 Subject: [PATCH 146/166] Remove payments CSV export. The implementation made it really difficult to reorganize to a new chain as the payments would have to be cut out from a concatenated string. The information is still in the chain but those who wants to export the data to CSV will have to traverse the chain manually. --- src/global_objects_noui.hpp | 4 -- src/main.cpp | 23 +------- src/rpcblockchain.cpp | 115 ------------------------------------ 3 files changed, 1 insertion(+), 141 deletions(-) diff --git a/src/global_objects_noui.hpp b/src/global_objects_noui.hpp index 182d7b11f5..483101b3ab 100755 --- a/src/global_objects_noui.hpp +++ b/src/global_objects_noui.hpp @@ -68,10 +68,6 @@ struct StructCPID std::string email; std::string boincruntimepublickey; std::string cpidv2; - std::string PaymentTimestamps; - std::string PaymentAmountsResearch; - std::string PaymentAmountsInterest; - std::string PaymentAmountsBlocks; std::string BlockHash; std::string GRCAddress; }; diff --git a/src/main.cpp b/src/main.cpp index f9252796b9..ac67b84d35 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -167,7 +167,6 @@ void CheckForUpgrade(); int64_t GetRSAWeightByCPID(std::string cpid); extern MiningCPID GetMiningCPID(); extern StructCPID GetStructCPID(); -json_spirit::Array MagnitudeReportCSV(bool detail); int64_t nLastBlockSolved = 0; //Future timestamp int64_t nLastBlockSubmitted = 0; @@ -4456,23 +4455,8 @@ void GridcoinServices() } } - if (KeyEnabled("exportmagnitude")) - { - if (TimerMain("export_magnitude",900)) - { - json_spirit::Array results; - results = MagnitudeReportCSV(true); - - } - } - if (TimerMain("gather_cpids",480)) - { - //if (fDebug10) printf("\r\nReharvesting cpids in background thread...\r\n"); - //LoadCPIDsInBackground(); - //printf(" {CPIDs Re-Loaded} "); - msNeuralResponse=""; - } + msNeuralResponse.clear(); if (TimerMain("check_for_autoupgrade",240)) { @@ -5247,11 +5231,6 @@ void AddResearchMagnitude(CBlockIndex* pIndex) stMag.interestPayments += pIndex->nInterestSubsidy; AdjustTimestamps(stMag,pIndex->nTime, pIndex->nResearchSubsidy); - // Track detailed payments made to each CPID - stMag.PaymentTimestamps += ToString(pIndex->nTime) + ","; - stMag.PaymentAmountsResearch += RoundToString(pIndex->nResearchSubsidy,2) + ","; - stMag.PaymentAmountsInterest += RoundToString(pIndex->nInterestSubsidy,2) + ","; - stMag.PaymentAmountsBlocks += ToString(pIndex->nHeight) + ","; stMag.Accuracy++; stMag.AverageRAC = stMag.rac / (stMag.entries+.01); double total_owed = 0; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 0706d192a1..32f0962811 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -136,7 +136,6 @@ int64_t GetRSAWeightByCPID(std::string cpid); double GetUntrustedMagnitude(std::string cpid, double& out_owed); extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry); int ReindexWallet(); -extern Array MagnitudeReportCSV(bool detail); std::string getfilecontents(std::string filename); int CreateRestorePoint(); int DownloadBlocks(); @@ -2749,19 +2748,6 @@ Array MagnitudeReport(std::string cpid) } - - -void CSVToFile(std::string filename, std::string data) -{ - boost::filesystem::path path = GetDataDir() / "reports" / filename; - boost::filesystem::create_directories(path.parent_path()); - ofstream myCSV; - myCSV.open (path.string().c_str()); - myCSV << data; - myCSV.close(); -} - - std::string TimestampToHRDate(double dtm) { if (dtm == 0) return "1-1-1970 00:00:00"; @@ -3746,100 +3732,11 @@ Array GetJSONVersionReport() } - - -Array MagnitudeReportCSV(bool detail) -{ - Array results; - Object c; - StructCPID globalmag = mvMagnitudes["global"]; - double payment_timespan = 14; - std::string Narr = "Research Savings Account Report - Generated " + ToString(GetAdjustedTime()) + " - Timespan: " + ToString(payment_timespan); - c.push_back(Pair("RSA Report",Narr)); - results.push_back(c); - double totalpaid = 0; - double lto = 0; - double rows = 0; - double outstanding = 0; - double totaloutstanding = 0; - std::string header = "CPID,GRCAddress,Magnitude,PaymentMagnitude,Accuracy,LongTermOwed14day,LongTermOwedDaily,Payments,InterestPayments,LastPaymentTime,CurrentDailyOwed,NextExpectedPayment,AvgDailyPayments,Outstanding,PaymentTimespan"; - - if (detail) header += ",PaymentDate,ResearchPaymentAmount,InterestPaymentAmount,Block#"; - header += "\r\n"; - - std::string row = ""; - for(map::iterator ii=mvMagnitudes.begin(); ii!=mvMagnitudes.end(); ++ii) - { - // For each CPID on the network, report: - StructCPID structMag = mvMagnitudes[(*ii).first]; - if (structMag.initialized && structMag.cpid.length() > 2) - { - if (IsResearcher(structMag.cpid)) - { - outstanding = structMag.totalowed - structMag.payments; - - StructCPID stDPOR = mvDPOR[structMag.cpid]; - - row = structMag.cpid + "," + structMag.GRCAddress + "," + RoundToString(structMag.Magnitude,2) + "," - + RoundToString(structMag.PaymentMagnitude,0) + "," + RoundToString(structMag.Accuracy,0) + "," + RoundToString(structMag.totalowed,2) - + "," + RoundToString(structMag.totalowed/14,2) - + "," + RoundToString(structMag.payments,2) + "," - + RoundToString(structMag.interestPayments,2) + "," + TimestampToHRDate(structMag.LastPaymentTime) - + "," + RoundToString(structMag.owed,2) - + "," + RoundToString(structMag.owed/2,2) - + "," + RoundToString(structMag.payments/14,2) + "," + RoundToString(outstanding,2) + "," - + RoundToString(structMag.PaymentTimespan,0) + "\n"; - header += row; - if (detail) - { - //Add payment detail - Halford - Christmas Eve 2014 - std::vector vCPIDTimestamps = split(structMag.PaymentTimestamps.c_str(),","); - std::vector vCPIDPayments = split(structMag.PaymentAmountsResearch.c_str(),","); - std::vector vCPIDInterestPayments = split(structMag.PaymentAmountsInterest.c_str(),","); - std::vector vCPIDPaymentBlocks = split(structMag.PaymentAmountsBlocks.c_str(),","); - - for (unsigned int i = 0; i < vCPIDTimestamps.size(); i++) - { - double dTime = RoundFromString(vCPIDTimestamps[i],0); - std::string sResearchAmount = vCPIDPayments[i]; - std::string sPaymentDate = DateTimeStrFormat("%m-%d-%Y %H:%M:%S", dTime); - std::string sInterestAmount = vCPIDInterestPayments[i]; - std::string sPaymentBlock = vCPIDPaymentBlocks[i]; - //std::string sPaymentHash = vCPIDPaymentBlockHashes[i]; - if (dTime > 0) - { - row = " , , , , , , , , , , , , , , , , " + sPaymentDate + "," + sResearchAmount + "," + sInterestAmount + "," + sPaymentBlock + "\n"; - header += row; - } - } - } - rows++; - totalpaid += structMag.payments; - lto += structMag.totalowed; - totaloutstanding += outstanding; - } - - } - - } - int64_t timestamp = GetTime(); - std::string footer = RoundToString(rows,0) + ", , , , ," + RoundToString(lto,2) + ", ," + RoundToString(totalpaid,2) + ", , , , , ," + RoundToString(totaloutstanding,2) + "\n"; - header += footer; - Object entry; - entry.push_back(Pair("CSV Complete",strprintf("\\reports\\magnitude_%" PRId64 ".csv",timestamp))); - results.push_back(entry); - - CSVToFile(strprintf("magnitude_%" PRId64 ".csv",timestamp), header); - return results; -} - std::string GetBurnAddress() { return fTestNet ? "mk1e432zWKH1MW57ragKywuXaWAtHy1AHZ" : "S67nL4vELWwdDVzjgtEP4MxryarTZ9a8GB"; } - - std::string BurnCoinsWithNewContract(bool bAdd, std::string sType, std::string sPrimaryKey, std::string sValue, int64_t MinimumBalance, double dFees, std::string strPublicKey, std::string sBurnAddress) { @@ -4061,16 +3958,6 @@ Value listitem(const Array& params, bool fHelp) entry.push_back(Pair("UTC",TimestampToHRDate(GetAdjustedTime()))); results.push_back(entry); - } - else if (sitem == "magnitudecsv") - { - results = MagnitudeReportCSV(false); - return results; - } - else if (sitem=="detailmagnitudecsv") - { - results = MagnitudeReportCSV(true); - return results; } else if (sitem == "seefile") { @@ -4250,11 +4137,9 @@ Value listitem(const Array& params, bool fHelp) Object entry; entry.push_back(Pair("list cpids", "Displays information on cpids and the projects they are associated with")); entry.push_back(Pair("list currenttime", "Displays current unix time as well as UTC time and date")); - entry.push_back(Pair("list detailmagnitudecsv", "Records more detailed magnitude report into a csv file")); entry.push_back(Pair("list explainmagnitude ", "Displays information about your magnitude from NN; Optional true to force response")); entry.push_back(Pair("list lifetime", "Displays information on the life time of your cpid")); entry.push_back(Pair("list magnitude ", "Displays information on magnitude. cpid is optional.")); - entry.push_back(Pair("list magnitudecsv", "Records magnitude report into a csv file")); entry.push_back(Pair("list memorypool", "Displays information currently on Txs in memory pool")); entry.push_back(Pair("list network", "Displays detailed information on the network")); entry.push_back(Pair("list projects", "Displays information on whitelisted projects on the network")); From ee32e121c2cca0805ccf39cff7d5671c577f03fa Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sun, 10 Dec 2017 10:09:07 +0100 Subject: [PATCH 147/166] Remove the now unused GRC address from block index. --- src/global_objects_noui.hpp | 1 - src/main.cpp | 2 -- src/main.h | 15 ++++++++------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/global_objects_noui.hpp b/src/global_objects_noui.hpp index 483101b3ab..e9dfe2af48 100755 --- a/src/global_objects_noui.hpp +++ b/src/global_objects_noui.hpp @@ -69,7 +69,6 @@ struct StructCPID std::string boincruntimepublickey; std::string cpidv2; std::string BlockHash; - std::string GRCAddress; }; diff --git a/src/main.cpp b/src/main.cpp index ac67b84d35..df61a5b9bb 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3065,7 +3065,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck, boo } iPos++; } - pindex->sGRCAddress = bb.GRCAddress; } double mint = CoinToDouble(pindex->nMint); @@ -5221,7 +5220,6 @@ void AddResearchMagnitude(CBlockIndex* pIndex) { StructCPID stMag = GetInitializedStructCPID2(pIndex->GetCPID(),mvMagnitudesCopy); stMag.cpid = pIndex->GetCPID(); - stMag.GRCAddress = pIndex->sGRCAddress; if (pIndex->nHeight > stMag.LastBlock) { stMag.LastBlock = pIndex->nHeight; diff --git a/src/main.h b/src/main.h index 775878884b..44365d733e 100755 --- a/src/main.h +++ b/src/main.h @@ -1311,7 +1311,6 @@ class CBlockIndex // Indicators (9-13-2015) unsigned int nIsSuperBlock; unsigned int nIsContract; - std::string sGRCAddress; unsigned int nFlags; // ppcoin: block index flags enum @@ -1368,7 +1367,6 @@ class CBlockIndex nMagnitude = 0; nIsSuperBlock = 0; nIsContract = 0; - sGRCAddress = ""; } CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) @@ -1627,12 +1625,15 @@ class CDiskBlockIndex : public CBlockIndex { READWRITE(nIsSuperBlock); READWRITE(nIsContract); - READWRITE(sGRCAddress); - // Blocks used to come with a reserved string. Keep (de)serializing - // it until it's used. - std::string sReserved; - READWRITE(sReserved); + std::string dummy; + + // Blocks used to contain the GRC address. + READWRITE(dummy); + + // Blocks used to come with a reserved string. Keep (de)serializing + // it until it's used. + READWRITE(dummy); } From 9d22c6e1167026b823531ea9320fca9a5ac8c93e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Fri, 15 Dec 2017 19:58:04 +0100 Subject: [PATCH 148/166] Calculate and if debug2 print difficulty of found kernel in miner. --- src/miner.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 798b650b1e..f1ab2b541c 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -434,6 +434,8 @@ bool CreateCoinStake( CBlock &blocknew, CKey &key, int64_t StakeWeightMin=MAX_MONEY; int64_t StakeWeightMax=0; uint64_t StakeCoinAgeSum=0; + double StakeDiffSum = 0; + double StakeDiffMax = 0; CTransaction &txnew = blocknew.vtx[1]; // second tx is coinstake //initialize the transaction @@ -519,6 +521,9 @@ bool CreateCoinStake( CBlock &blocknew, CKey &key, StakeWeightSum += CoinWeight; StakeWeightMin=std::min(StakeWeightMin,CoinWeight); StakeWeightMax=std::max(StakeWeightMax,CoinWeight); + double StakeKernelDiff = GetBlockDifficulty(StakeKernelHash.GetCompact())*CoinWeight; + StakeDiffSum += StakeKernelDiff; + StakeDiffMax = std::max(StakeDiffMax,StakeKernelDiff); if (fDebug2) { int64_t RSA_WEIGHT = GetRSAWeightByBlock(GlobalCPUMiningCPID); @@ -526,13 +531,15 @@ bool CreateCoinStake( CBlock &blocknew, CKey &key, "CreateCoinStake: V%d Time %.f, Por_Nonce %.f, Bits %jd, Weight %jd\n" " RSA_WEIGHT %.f\n" " Stk %72s\n" -" Trg %72s\n", +" Trg %72s\n" +" Diff %0.7f of %0.7f\n", blocknew.nVersion, (double)txnew.nTime, mdPORNonce, (intmax_t)blocknew.nBits,(intmax_t)CoinWeight, (double)RSA_WEIGHT, - StakeKernelHash.GetHex().c_str(), StakeTarget.GetHex().c_str() - ); + StakeKernelHash.GetHex().c_str(), StakeTarget.GetHex().c_str(), + StakeKernelDiff, GetBlockDifficulty(blocknew.nBits) + ); } if( StakeKernelHash <= StakeTarget ) From fcb9d06e459a4ccfd2bf9e8c3ddfb43cac8f7279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Fri, 15 Dec 2017 20:00:25 +0100 Subject: [PATCH 149/166] Add best found kernel difficulty and sum to Miner status and getmininginfo rpc. --- src/miner.cpp | 6 ++++++ src/miner.h | 2 ++ src/rpcmining.cpp | 3 +++ 3 files changed, 11 insertions(+) diff --git a/src/miner.cpp b/src/miner.cpp index f1ab2b541c..ca61886e29 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -66,6 +66,8 @@ void CMinerStatus::Clear() WeightSum= ValueSum= WeightMin= WeightMax= 0; Version= 0; CoinAgeSum= 0; + KernelDiffMax = 0; + KernelDiffSum = 0; nLastCoinStakeSearchInterval = 0; } @@ -600,6 +602,8 @@ bool CreateCoinStake( CBlock &blocknew, CKey &key, LOCK(MinerStatus.lock); MinerStatus.Message+="Found Kernel "+ ToString(CoinToDouble(nCredit))+"; "; MinerStatus.KernelsFound++; + MinerStatus.KernelDiffMax = 0; + MinerStatus.KernelDiffSum = StakeDiffSum; return true; } } @@ -611,6 +615,8 @@ bool CreateCoinStake( CBlock &blocknew, CKey &key, MinerStatus.WeightMin=StakeWeightMin; MinerStatus.WeightMax=StakeWeightMax; MinerStatus.CoinAgeSum=StakeCoinAgeSum; + MinerStatus.KernelDiffMax = std::max(MinerStatus.KernelDiffMax,StakeDiffMax); + MinerStatus.KernelDiffSum = StakeDiffSum; MinerStatus.nLastCoinStakeSearchInterval= txnew.nTime; return false; } diff --git a/src/miner.h b/src/miner.h index d3a4a799bf..29a983031b 100644 --- a/src/miner.h +++ b/src/miner.h @@ -22,6 +22,8 @@ struct CMinerStatus uint64_t AcceptedCnt; uint64_t KernelsFound; int64_t nLastCoinStakeSearchInterval; + double KernelDiffMax; + double KernelDiffSum; void Clear(); CMinerStatus() diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 610d55860a..cfadc70762 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -67,6 +67,9 @@ Value getmininginfo(const Array& params, bool fHelp) // reuse value found by miner which has to load blocks anyway double dInterest = MinerStatus.CoinAgeSum * GetCoinYearReward(nTime) * 33 / (365 * 33 + 8); obj.push_back(Pair("InterestPending",dInterest/(double)COIN)); + + obj.push_back(Pair("kernel-diff-best",MinerStatus.KernelDiffMax)); + obj.push_back(Pair("kernel-diff-sum",MinerStatus.KernelDiffSum)); } obj.push_back(Pair("difficulty", diff)); From c91ce3165ee4a05a24fe40ac4c65678344615cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sat, 16 Dec 2017 13:14:43 +0100 Subject: [PATCH 150/166] Do not reset MinerStatus.KernelDiffMax on Clear when mining becomes not allowed. This makes KernelDiffMax represent best kernel of wallet runtime. --- src/miner.cpp | 9 ++++++++- src/miner.h | 7 +------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index ca61886e29..69b8404b31 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -60,13 +60,20 @@ class COrphan } }; +CMinerStatus::CMinerStatus(void) +{ + Clear(); + ReasonNotStaking= ""; + CreatedCnt= AcceptedCnt= KernelsFound= 0; + KernelDiffMax= 0; +} + void CMinerStatus::Clear() { Message= ""; WeightSum= ValueSum= WeightMin= WeightMax= 0; Version= 0; CoinAgeSum= 0; - KernelDiffMax = 0; KernelDiffSum = 0; nLastCoinStakeSearchInterval = 0; } diff --git a/src/miner.h b/src/miner.h index 29a983031b..944d02724c 100644 --- a/src/miner.h +++ b/src/miner.h @@ -26,12 +26,7 @@ struct CMinerStatus double KernelDiffSum; void Clear(); - CMinerStatus() - { - Clear(); - ReasonNotStaking= ""; - CreatedCnt= AcceptedCnt= KernelsFound= 0; - } + CMinerStatus(); }; extern CMinerStatus MinerStatus; From d1c866330a78a39ce59a68a4a361eca2f10bd22d Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 19 Dec 2017 07:05:16 +0100 Subject: [PATCH 151/166] Use !empty instead of empty == false. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index d4e64f3a88..b2f6cc0354 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3388,7 +3388,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) printf("REORGANIZE: Disconnect %" PRIszu " blocks; %s..%s\n", vDisconnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexBest->GetBlockHash().ToString().substr(0,20).c_str()); printf("REORGANIZE: Connect %" PRIszu " blocks; %s..%s\n", vConnect.size(), pfork->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->GetBlockHash().ToString().substr(0,20).c_str()); - if (vDisconnect.empty() == false) + if (!vDisconnect.empty()) { //Block was disconnected - User is Re-eligibile for staking From 8e6d9f388784f8adf3587013fec1fef39d46efa7 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 21 Dec 2017 06:17:15 +0100 Subject: [PATCH 152/166] Update changelog. --- CHANGELOG.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e70fe33fe..a2ebcdb116 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,61 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [3.7.0.0] +### Added + - Provide Difficulty of best kernel found, #766 (@tomasbrod). + - Add Travis support for OSX, 665 (@acey1). + - Add better command for sending alerts, #731 (@tomasbrod). + - Add RPC for sending raw contracts, #683 (@tomasbrod). + - Add portable diagnostic page, #631 (@fooforever). + +### Fixed + - Fixed minor spelling mistakes, #742 (@denravonska). + - Several tally improvements. There should now be less forking and the wallet + should use ~50MB less memory, #668, #756 (@denravonska, @tomasbrod) + - Data scraper can no longer run concurrently, #742 (@denravonska). + - Improve superblock validations, #730 (@tomasbrod). + - Fix potential deadlock, #708 (@denravonska). + - Prevent duplicate superblocks, #534 (@tomasbrod). + - Fix issue with application cache clears, #577 (@tomasbrod). + - Fix bug which caused rewards to be lost when staking the newbie block. + Missing rewards will be reimbursed, #552 (@Foggyx420). + - Fix minor UI typos, #661 (@Erkan-Yilmaz). + - Fix stake modifier, #686 (@tomasbrod). + +### Changed + - Changed versioning extraction from git. Test builds can no longer be used to + stake in production unless explicitly enabled, #729 (@tomasbrod). + - Don't update network quorum while syncing, #728 (@Foggyx420). + - Snapshot URL now uses https, #727 (@Foggyx420). + - Code cleanup (@Foggyx420, @denravonska). + - Use more efficient data structure for blocks, #679 (@denravonska). + - Improve transaction description dialog, #676 (@Foggyx420). + - Improve beacon handling, #604, #645, #649, #684, #701 (@Foggyx420, @tomasbrod). + - Optimize double<->string conversions, #692 (@denravonska). + - Optimize application cache access, #506 (@denravonska). + - Improve thread handling, #656 (@skcin). + - Replace `boost::shared_ptr` with `std::shared_ptr`. + - Optimize string split function, #672 (@denravonska). + - Improve sync speeds, #650 (@denravonska). + - The RPC command `restartclient` is now called `restart`. + - Fix voting sorting issues, #610 (@MagixInTheAir). + - Improve wallet backup, #610 (@Foggyx420). + +### Removed + - Remove CSV exporter which used unreliable data, #759 (@denravonska). + - Remove block download menu options on non-Windows, #727 (@Foggyx420). + - Removed RPC commands (@Foggyx420, @denravonska): + - debugexplainmagnitude + - executecode + - getsubsidy + - list newbieage + - list staking + - leder + - reboot + - Remove checkpoint relaying to improve sync speeds, #678 (@denravonska). + - Remove IRC peer discovery. + ## [3.6.3.0] 2017-10-09 ### Fixed - Fix problems sending beacons on Windows, #684 (@tomasbrod). From 5f828d4831635cf3deab7578680d042a331fd570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Brada?= Date: Sat, 23 Dec 2017 10:43:31 +0100 Subject: [PATCH 153/166] Transaction View crash. #785 --- src/rpcrawtransaction.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index fd3e089895..44bf3531dd 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -249,17 +249,20 @@ std::vector> GetTxNormalBoincHashInfo(const CBlockIndex* pblockindex = mapBlockIndex[mtx.hashBlock]; CBlock block; - int nEndHeight = pblockindex->nHeight - (BLOCKS_PER_DAY*14); + if(pblockindex) + { + int nEndHeight = pblockindex->nHeight - (BLOCKS_PER_DAY*14); - // Incase; Why throw. - if (nEndHeight < 1) - nEndHeight = 1; + // Incase; Why throw. + if (nEndHeight < 1) + nEndHeight = 1; - // Iterate back to find previous superblock - while (pblockindex->nHeight > nEndHeight && pblockindex->nIsSuperBlock == 0) - pblockindex = pblockindex->pprev; + // Iterate back to find previous superblock + while (pblockindex->nHeight > nEndHeight && pblockindex->nIsSuperBlock == 0) + pblockindex = pblockindex->pprev; + } - if (pblockindex->nIsSuperBlock == 1) + if (pblockindex && pblockindex->nIsSuperBlock) { block.ReadFromDisk(pblockindex); @@ -315,7 +318,10 @@ std::vector> GetTxNormalBoincHashInfo(const { res.push_back(std::make_pair(_("ERROR"), _("Unable to obtain superblock data before vote was made to calculate voting weight"))); - return res; + dVoteWeight = -1; + res.push_back(std::make_pair(_("Magnitude"), RoundToString(dVoteMagnitude, 2))); + res.push_back(std::make_pair(_("Balance"), RoundToString(dVoteBalance, 2))); + } } From f8ddfe0385d03b36d36fe0c5e01d66c7fb94f8b1 Mon Sep 17 00:00:00 2001 From: barton26 Date: Wed, 27 Dec 2017 04:32:09 -0500 Subject: [PATCH 154/166] Hard Coded Seed Node Cleanup (#783) * Hard Coded Seednode Cleanup Reference Issue #764 Removed dead node (gridcoin.asia) Removed duplicates (frankfurt, amsterdam) Added two new seed nodes (nuad.de and www.grcpool.com) * Update bitcoingui.cpp and Linux Guide * Add gridcoinstats.eu node * Add ifoggz seed record --- CompilingGridcoinOnLinux.txt | 1 - src/net.cpp | 7 ++++--- src/qt/bitcoingui.cpp | 13 ++++++------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/CompilingGridcoinOnLinux.txt b/CompilingGridcoinOnLinux.txt index 6fbf4a8fe6..6bfcbc722e 100644 --- a/CompilingGridcoinOnLinux.txt +++ b/CompilingGridcoinOnLinux.txt @@ -169,7 +169,6 @@ email= rpcuser= rpcpassword= addnode=node.gridcoin.us -addnode=gridcoin.asia Ctrl-X to exit and save diff --git a/src/net.cpp b/src/net.cpp index 815959e43d..a37c17e4a1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1476,10 +1476,11 @@ void MapPort() // The second name should resolve to a list of seed addresses. static const char *strDNSSeed[][2] = { {"node.gridcoin.us", "node.gridcoin.us"}, - {"gridcoin.asia", "gridcoin.asia"}, - {"amsterdam.grcnode.co.uk", "amsterdam.grcnode.co.uk"}, {"london.grcnode.co.uk", "london.grcnode.co.uk"}, - {"frankfurt.grcnode.co.uk", "frankfurt.grcnode.co.uk"}, + {"gridcoin.crypto.fans", "gridcoin.crypto.fans"}, + {"www.grcpool.com", "www.grcpool.com"}, + {"nuad.de", "nuad.de"}, + {"seeds.gridcoin.ifoggz-network.xyz", "seeds.gridcoin.ifoggz-network.xyz"}, {"", ""}, }; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index a3e13641c4..5353cc87e4 100755 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1211,9 +1211,9 @@ bool CreateNewConfigFile(std::string boinc_email) myConfig << row; row = "addnode=node.gridcoin.us \r\n"; myConfig << row; - row = "addnode=gridcoin.asia \r\n"; + row = "addnode=www.grcpool.com \r\n"; myConfig << row; - row = "addnode=grcmagnitude.com \r\n"; + row = "addnode=seeds.gridcoin.ifoggz-network.xyz \r\n"; myConfig << row; myConfig.close(); return true; @@ -1279,12 +1279,11 @@ void BitcoinGUI::NewUserWizard() ReadConfigFile(mapArgs, mapMultiArgs); //Force some addnodes in to get user started ForceInAddNode("node.gridcoin.us"); - ForceInAddNode("gridcoin.asia"); - ForceInAddNode("grcmagnitude.com"); - ForceInAddNode("amsterdam.grcnode.co.uk"); ForceInAddNode("london.grcnode.co.uk"); - ForceInAddNode("frankfurt.grcnode.co.uk"); - ForceInAddNode("nyc.grcnode.co.uk"); + ForceInAddNode("gridcoin.crypto.fans"); + ForceInAddNode("seeds.gridcoin.ifoggz-network.xyz"); + ForceInAddNode("nuad.de"); + ForceInAddNode("www.grcpool.com"); if (sBoincNarr != "") { From 6aef75c184a460f6a1cd236f8d4f25d47283a916 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Wed, 27 Dec 2017 10:33:55 +0100 Subject: [PATCH 155/166] Update changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2ebcdb116..3469ffe250 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - The RPC command `restartclient` is now called `restart`. - Fix voting sorting issues, #610 (@MagixInTheAir). - Improve wallet backup, #610 (@Foggyx420). + - Update seed nodes, #783 (@barton2526). ### Removed - Remove CSV exporter which used unreliable data, #759 (@denravonska). From 9d6229ff2e647e48e04c9055efc16705c4f7d3fe Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 1 Jan 2018 06:33:25 +0100 Subject: [PATCH 156/166] Update version numbers. --- contrib/Installer/boinc/boinc/Utilization.vb | 4 ++-- src/clientversion.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/Installer/boinc/boinc/Utilization.vb b/contrib/Installer/boinc/boinc/Utilization.vb index e5dfd765b5..6082551e1c 100644 --- a/contrib/Installer/boinc/boinc/Utilization.vb +++ b/contrib/Installer/boinc/boinc/Utilization.vb @@ -14,7 +14,7 @@ Public Class Utilization Private mlSpeakMagnitude As Double Public ReadOnly Property Version As Double Get - Return 424 + Return 425 End Get End Property @@ -555,4 +555,4 @@ End Class Public Interface IGridcoinMining -End Interface \ No newline at end of file +End Interface diff --git a/src/clientversion.h b/src/clientversion.h index a3b6f06370..d060f41c02 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -7,9 +7,9 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 3 -#define CLIENT_VERSION_MINOR 6 -#define CLIENT_VERSION_REVISION 3 -#define CLIENT_VERSION_BUILD 17 +#define CLIENT_VERSION_MINOR 7 +#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_BUILD 0 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! @@ -17,4 +17,4 @@ #define DO_STRINGIZE(X) #X #endif // CLIENTVERSION_H - \ No newline at end of file + From f4ad2ba84592968b39a9a80f6da79db20392a280 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 1 Jan 2018 07:15:54 +0100 Subject: [PATCH 157/166] Update build dependencies: - Qt5 - boost - libjpeg - zlib - libqrencode --- contrib/easywinbuilder/3a_build_boost.bat | 14 ++-------- contrib/easywinbuilder/3b_run_build_dep.bat | 4 +-- contrib/easywinbuilder/4b_build_qt.bat | 9 +++---- contrib/easywinbuilder/6_gather_dlls.bat | 20 +++++++------- contrib/easywinbuilder/build_dep.sh | 30 +++++++++++++++------ contrib/easywinbuilder/set_vars.bat | 30 ++++++++++----------- 6 files changed, 55 insertions(+), 52 deletions(-) diff --git a/contrib/easywinbuilder/3a_build_boost.bat b/contrib/easywinbuilder/3a_build_boost.bat index 90004f083b..757bc348d8 100644 --- a/contrib/easywinbuilder/3a_build_boost.bat +++ b/contrib/easywinbuilder/3a_build_boost.bat @@ -3,20 +3,10 @@ @cd %ROOTPATH%\%EWBLIBS%\%BOOST% @echo bootstrap... -call bootstrap.bat mingw +call bootstrap.bat gcc @echo. @echo. @echo building... -b2.exe --build-type=minimal --with-chrono --with-filesystem --with-program_options --with-system --with-thread^ - --layout=versioned -sNO_BZIP2=1 -sNO_ZLIB=1^ - variant=release^ - toolset=gcc^ - link=static^ - threading=multi^ - target-os=windows^ - threadapi=win32^ - cxxflags="%ADDITIONALCCFLAGS%"^ - cflags="%ADDITIONALCCFLAGS%"^ - stage +b2.exe --build-type=minimal --with-chrono --with-filesystem --with-program_options --with-system --with-thread toolset=gcc variant=release link=static threading=multi runtime-link=static --layout=versioned -sNO_BZIP2=1 -sNO_ZLIB=1 target-os=windows threadapi=win32 cxxflags="%ADDITIONALCCFLAGS%" cflags="%ADDITIONALCCFLAGS%" stage @cd ..\..\%EWBPATH% @if not "%RUNALL%"=="1" pause diff --git a/contrib/easywinbuilder/3b_run_build_dep.bat b/contrib/easywinbuilder/3b_run_build_dep.bat index f726e429c5..3221d858f0 100644 --- a/contrib/easywinbuilder/3b_run_build_dep.bat +++ b/contrib/easywinbuilder/3b_run_build_dep.bat @@ -1,3 +1,3 @@ @call set_vars.bat -@rxvt -e ./build_dep.sh -@if not "%RUNALL%"=="1" pause \ No newline at end of file +@bash ./build_dep.sh +@if not "%RUNALL%"=="1" pause diff --git a/contrib/easywinbuilder/4b_build_qt.bat b/contrib/easywinbuilder/4b_build_qt.bat index dedbff099d..fdfc572282 100644 --- a/contrib/easywinbuilder/4b_build_qt.bat +++ b/contrib/easywinbuilder/4b_build_qt.bat @@ -11,9 +11,6 @@ @echo building qt - qmake... @set COINNAME=Gridcoin - -echo %EWBLIBS% - @set QMPS=BOOST_INCLUDE_PATH=%EWBLIBS%/%BOOST%^ BOOST_LIB_PATH=%EWBLIBS%/%BOOST%/stage/lib^ BOOST_LIB_SUFFIX=%BOOSTSUFFIX%^ @@ -27,10 +24,12 @@ echo %EWBLIBS% LIBZIP_LIB_PATH=%EWBLIBS%/libzip/lib^ MINIUPNPC_INCLUDE_PATH=%EWBLIBS%/%MINIUPNPC%^ MINIUPNPC_LIB_PATH=%EWBLIBS%/%MINIUPNPC%^ + QRENCODE_INCLUDE_PATH=%EWBLIBS%/%QRENCODE%^ + QRENCODE_LIB_PATH=%EWBLIBS%/%QRENCODE%/.libs^ QMAKE_CXXFLAGS="%ADDITIONALCCFLAGS%"^ QMAKE_CFLAGS="%ADDITIONALCCFLAGS%" - -@%QTPATH%\qmake.exe %QMPS% USE_QRCODE=0 ZZZ=1 + +@qmake.exe %QMPS% USE_QRCODE=1 ZZZ=1 @echo. @echo. @echo building qt - make... diff --git a/contrib/easywinbuilder/6_gather_dlls.bat b/contrib/easywinbuilder/6_gather_dlls.bat index 38eea18775..4ba5d8cd34 100644 --- a/contrib/easywinbuilder/6_gather_dlls.bat +++ b/contrib/easywinbuilder/6_gather_dlls.bat @@ -1,11 +1,11 @@ @call set_vars.bat -copy %QTPATH%\QtCore4.dll %ROOTPATH%\release\ -copy %QTPATH%\QtGui4.dll %ROOTPATH%\release\ -copy %QTPATH%\QtNetwork4.dll %ROOTPATH%\release\ -copy C:\MinGW\bin\libgcc_s_dw2-1.dll %ROOTPATH%\release\ -copy "C:\MinGW\bin\libstdc++-6.dll" %ROOTPATH%\release\ -copy C:\MinGW\bin\mingwm10.dll %ROOTPATH%\release\ - -copy C:\MinGW\bin\libgcc_s_dw2-1.dll %ROOTPATH%\src\ -copy "C:\MinGW\bin\libstdc++-6.dll" %ROOTPATH%\src\ -@if not "%RUNALL%"=="1" pause \ No newline at end of file +copy %QTPATH%\Qt5Charts.dll %ROOTPATH%\release\ +copy %QTPATH%\Qt5Core.dll %ROOTPATH%\release\ +copy %QTPATH%\Qt5Gui.dll %ROOTPATH%\release\ +copy %QTPATH%\Qt5Network.dll %ROOTPATH%\release\ +copy %QTPATH%\Qt5Widgets.dll %ROOTPATH%\release\ +copy %MINGW%\bin\libgcc_s_dw2-1.dll %ROOTPATH%\release\ +copy %MINGW%\bin\libstdc++-6.dll %ROOTPATH%\release\ +copy %MINGW%\bin\libgcc_s_dw2-1.dll %ROOTPATH%\release\ +copy %MINGW%\bin\libwinpthread-1.dll %ROOTPATH%\release\ +@if not "%RUNALL%"=="1" pause diff --git a/contrib/easywinbuilder/build_dep.sh b/contrib/easywinbuilder/build_dep.sh index d6ea2681e9..da528d58bd 100644 --- a/contrib/easywinbuilder/build_dep.sh +++ b/contrib/easywinbuilder/build_dep.sh @@ -11,24 +11,38 @@ fi cd $ROOTPATHSH/$EWBLIBS +echo libpng.. +cd ${LIBPNG} +make -j2 -f scripts/makefile.gcc +cd .. +echo + +echo qrencode.. +cd ${QRENCODE} +png_CFLAGS="-I${LIBPNG}" \ +png_LIBS="-L${LIBPNG}/.libs -lpng" \ +./configure --enable-static --disable-shared --without-tools +make -j2 +cd .. +echo + echo db... -cd $BERKELEYDB -cd build_unix +cd $BERKELEYDB/build_unix ../dist/configure --disable-replication --enable-mingw --enable-cxx \ CXXFLAGS="${ADDITIONALCCFLAGS}" \ CFLAGS="${ADDITIONALCCFLAGS}" sed -i 's/typedef pthread_t db_threadid_t;/typedef u_int32_t db_threadid_t;/g' db.h # workaround, see https://bitcointalk.org/index.php?topic=45507.0 -make -cd .. -cd .. +make -j2 +cd ../.. echo echo openssl... cd $OPENSSL export CC="gcc ${ADDITIONALCCFLAGS}" -./config -make +./Configure mingw + +make -j2 cd .. echo -cd ../$EWBPATH \ No newline at end of file +cd ../$EWBPATH diff --git a/contrib/easywinbuilder/set_vars.bat b/contrib/easywinbuilder/set_vars.bat index 474267bd4a..fb2e4d5610 100644 --- a/contrib/easywinbuilder/set_vars.bat +++ b/contrib/easywinbuilder/set_vars.bat @@ -1,26 +1,24 @@ -@set PATH=a:\mingw\msys\1.0\bin;a:\mingw\bin - @set LANG=en_US.UTF8 @set LC_ALL=en_US.UTF8 @set MINGWINSTALLER=mingw-get-inst-20120426 -@set OPENSSL=openssl-1.0.1e +@set OPENSSL=openssl-1.0.2l @set BERKELEYDB=db-4.8.30.NC -@set BOOST=boost_1_55_0 -@set BOOSTVERSION=1.55.0 +@set BOOST=boost_1_64_0 +@set BOOSTVERSION=1.64.0 @set LEVELDB=leveldb -@rem If you wonder why there is no -s- see: https://github.com/bitcoin/bitcoin/pull/2835#issuecomment-21231694 -@set BOOSTSUFFIX=-mgw46-mt-1_55 +@set BOOSTSUFFIX=-mgw53-mt-s-1_64 @set MINIUPNPC=miniupnpc-1.9 +@set QRENCODE=qrencode-3.4.4 +@set LIBPNG=lpng1629 +@set ZLIB=zlib @set EWBLIBS=libs - -set QTDIR=A:\Qt\4.8.4 -set QMAKESPEC=A:\Qt\4.8.4\mkspecs\win32-g++ -set PATH=%PATH%;a:\qt\4.8.4\qmake\bin -@set QTPATH=a:\Qt\4.8.4\bin +@set QTDIR=A:\Qt\Qt5.8.0 +@set PATH=%QTDIR%\Tools\mingw530_32\bin;%QTDIR%\5.8\mingw53_32\bin;%PATH% +@set QMAKESPEC=%QTDIR%\5.8\mingw53_32\mkspecs\win32-g++ @set EWBPATH=contrib/easywinbuilder set ROOTPATH=..\.. @@ -37,10 +35,12 @@ xset ROOTPATH=a:\gridcoin-research @set QTDOWNLOADPATH=http://download.qt-project.org/official_releases/qt/4.8/4.8.5/qt-win-opensource-4.8.5-mingw.exe @rem Qt5 will need changes in gather_dlls.bat -@set MSYS=a:/MinGW/msys/1.0/bin -@set PERL=%MSYS%/perl.exe +rem @set MINGW=%QTMINGW% +@set MSYS=a:\msys\1.0\bin +@set PERL=a:/msys/1.0/bin/perl.exe +set PATH=%MSYS%;%PATH% @rem the following will be set as additional CXXFLAGS and CFLAGS for everything - no ' or ", space is ok @set ADDITIONALCCFLAGS=-fno-guess-branch-probability -frandom-seed=1984 -Wno-unused-variable -Wno-unused-value -Wno-sign-compare -Wno-strict-aliasing -@rem Note: Variables set here can NOT be overwritten in makefiles \ No newline at end of file +@rem Note: Variables set here can NOT be overwritten in makefiles From dbe1543af301bb219b04b1f49e7b0dae404ead37 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 1 Jan 2018 08:35:26 +0100 Subject: [PATCH 158/166] Drop Qt4 support. - Add missing Qt widgets and concurrent modules - Fix broken version check for QtCharts (#790) - Adapt to variant and table header changes in Qt5 --- gridcoinresearch.pro | 19 +++---------------- src/qt/addressbookpage.cpp | 14 +------------- src/qt/overviewpage.cpp | 2 +- src/qt/transactionview.cpp | 18 +++--------------- src/qt/votingdialog.cpp | 8 -------- 5 files changed, 8 insertions(+), 53 deletions(-) diff --git a/gridcoinresearch.pro b/gridcoinresearch.pro index e502a72df7..2077cd8db1 100755 --- a/gridcoinresearch.pro +++ b/gridcoinresearch.pro @@ -4,31 +4,18 @@ VERSION = 3.1.0.1 INCLUDEPATH += src src/json src/qt DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE CONFIG += no_include_pwd thread c++11 exceptions concurrent -QT += core gui network +QT += core gui network widgets concurrent win32 { DEFINES += _WIN32_WINNT=0x0501 WINVER=0x0501 __USE_MINGW_ANSI_STDIO - lessThan(QT_VERSION, 5.0.0) { - CONFIG += qaxcontainer - } - else { - QT += axcontainer - } + QT += axcontainer # Fix for boost.asio build error. See # https://stackoverflow.com/questions/20957727/boostasio-unregisterwaitex-has-not-been-declared DEFINES += _WIN32_WINNT=0x0501 WINVER=0x0501 } -greaterThan(QT_MAJOR_VERSION, 4) { - QT += widgets concurrent - DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 -} else { - # qmake from Qt4 has no C++11 config so it has to be specified manually. - QMAKE_CXXFLAGS += -std=gnu++0x -} - -lessThan(QT_VERSION, 5.8.0) { +lessThan(QT_MAJOR_VERSION, 5) | lessThan(QT_MINOR_VERSION, 8) { # Qt charts not available }else{ QT += charts diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 1c0d3bda87..cdd35840e0 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -132,21 +132,9 @@ void AddressBookPage::setModel(AddressTableModel *model) ui->tableView->sortByColumn(0, Qt::AscendingOrder); // Set column widths - -#if QT_VERSION < 0x050000 - ui->tableView->horizontalHeader()->resizeSection( - AddressTableModel::Address, 320); - ui->tableView->horizontalHeader()->setResizeMode( - AddressTableModel::Label, QHeaderView::Stretch); -#else ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch); ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents); -#endif - - ui->tableView->horizontalHeader()->resizeSection( - AddressTableModel::Address, 320); - ui->tableView->horizontalHeader()->setResizeMode( - AddressTableModel::Label, QHeaderView::Stretch); + ui->tableView->horizontalHeader()->resizeSection(AddressTableModel::Address, 320); connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged())); diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index a0a25e8ce1..58d562f67d 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -64,7 +64,7 @@ class TxViewDelegate : public QAbstractItemDelegate QVariant value = index.data(Qt::ForegroundRole); //QColor foreground = option.palette.color(QPalette::Text); - if(qVariantCanConvert(value)) + if(value.canConvert(QMetaType::QColor)) { foreground = qvariant_cast(value); } diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 3bda05e652..cba5f48423 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -80,17 +80,14 @@ TransactionView::TransactionView(QWidget *parent) : hlayout->addWidget(typeWidget); addressWidget = new QLineEdit(this); -#if QT_VERSION >= 0x040700 - /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + /* TODO: Move this to the XML file */ addressWidget->setPlaceholderText(tr("Enter address or label to search")); -#endif hlayout->addWidget(addressWidget); amountWidget = new QLineEdit(this); -#if QT_VERSION >= 0x040700 - /* Do not move this to the XML file, Qt before 4.7 will choke on it */ + /* TODO: Move this to the XML file */ amountWidget->setPlaceholderText(tr("Min amount")); -#endif + #ifdef Q_OS_MAC amountWidget->setFixedWidth(97); #else @@ -182,19 +179,10 @@ void TransactionView::setModel(WalletModel *model) TransactionTableModel::Date, 120); transactionView->horizontalHeader()->resizeSection( TransactionTableModel::Type, 120); -#if QT_VERSION < 0x050000 - transactionView->horizontalHeader()->setResizeMode( - TransactionTableModel::ToAddress, QHeaderView::Stretch); -#else transactionView->horizontalHeader()->setSectionResizeMode( TransactionTableModel::ToAddress, QHeaderView::Stretch); -#endif - transactionView->horizontalHeader()->setResizeMode( - TransactionTableModel::ToAddress, QHeaderView::Stretch); transactionView->horizontalHeader()->resizeSection( TransactionTableModel::Amount, 100); - - } } diff --git a/src/qt/votingdialog.cpp b/src/qt/votingdialog.cpp index 319c590359..455fa68cd1 100644 --- a/src/qt/votingdialog.cpp +++ b/src/qt/votingdialog.cpp @@ -409,11 +409,7 @@ VotingDialog::VotingDialog(QWidget *parent) tableView_->setModel(proxyModel_); tableView_->setFont(QFont("Arial", 8)); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) tableView_->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); -#else - tableView_->horizontalHeader()->setResizeMode(QHeaderView::Interactive); -#endif tableView_->horizontalHeader()->setMinimumWidth(VOTINGDIALOG_WIDTH_RowNumber + VOTINGDIALOG_WIDTH_Title + VOTINGDIALOG_WIDTH_Expiration + VOTINGDIALOG_WIDTH_ShareType + VOTINGDIALOG_WIDTH_TotalParticipants + VOTINGDIALOG_WIDTH_TotalShares + VOTINGDIALOG_WIDTH_BestAnswer); groupboxvlayout->addWidget(tableView_); @@ -662,11 +658,7 @@ VotingChartDialog::VotingChartDialog(QWidget *parent) answerTable_->setRowCount(0); answerTableHeader<<"Answer"<<"Shares"<<"Percentage"; answerTable_->setHorizontalHeaderLabels(answerTableHeader); -#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) answerTable_->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); -#else - answerTable_->horizontalHeader()->setResizeMode(QHeaderView::Stretch); -#endif answerTable_->setEditTriggers( QAbstractItemView::NoEditTriggers ); resTabWidget->addTab(answerTable_, tr("List")); vlayout->addWidget(resTabWidget); From 968bd73292eb8a28299619ed036c9e1d3d717d59 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Tue, 2 Jan 2018 06:57:59 +0100 Subject: [PATCH 159/166] Fix invalid DLL paths when deploying. --- contrib/easywinbuilder/6_gather_dlls.bat | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/easywinbuilder/6_gather_dlls.bat b/contrib/easywinbuilder/6_gather_dlls.bat index 4ba5d8cd34..4696ef7826 100644 --- a/contrib/easywinbuilder/6_gather_dlls.bat +++ b/contrib/easywinbuilder/6_gather_dlls.bat @@ -4,8 +4,8 @@ copy %QTPATH%\Qt5Core.dll %ROOTPATH%\release\ copy %QTPATH%\Qt5Gui.dll %ROOTPATH%\release\ copy %QTPATH%\Qt5Network.dll %ROOTPATH%\release\ copy %QTPATH%\Qt5Widgets.dll %ROOTPATH%\release\ -copy %MINGW%\bin\libgcc_s_dw2-1.dll %ROOTPATH%\release\ -copy %MINGW%\bin\libstdc++-6.dll %ROOTPATH%\release\ -copy %MINGW%\bin\libgcc_s_dw2-1.dll %ROOTPATH%\release\ -copy %MINGW%\bin\libwinpthread-1.dll %ROOTPATH%\release\ +copy %QTPATH%\libgcc_s_dw2-1.dll %ROOTPATH%\release\ +copy %QTPATH%\libstdc++-6.dll %ROOTPATH%\release\ +copy %QTPATH%\libgcc_s_dw2-1.dll %ROOTPATH%\release\ +copy %QTPATH%\libwinpthread-1.dll %ROOTPATH%\release\ @if not "%RUNALL%"=="1" pause From 46fac6e0971c9d110fc51441c7476ae1b1bec532 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Tue, 2 Jan 2018 10:56:35 -0800 Subject: [PATCH 160/166] Add other dlls to copy for release. Fix libstc++-6.dll not being found as requires quotations --- contrib/easywinbuilder/6_gather_dlls.bat | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/contrib/easywinbuilder/6_gather_dlls.bat b/contrib/easywinbuilder/6_gather_dlls.bat index 4696ef7826..cb0ed1d914 100644 --- a/contrib/easywinbuilder/6_gather_dlls.bat +++ b/contrib/easywinbuilder/6_gather_dlls.bat @@ -1,11 +1,13 @@ @call set_vars.bat -copy %QTPATH%\Qt5Charts.dll %ROOTPATH%\release\ -copy %QTPATH%\Qt5Core.dll %ROOTPATH%\release\ -copy %QTPATH%\Qt5Gui.dll %ROOTPATH%\release\ -copy %QTPATH%\Qt5Network.dll %ROOTPATH%\release\ -copy %QTPATH%\Qt5Widgets.dll %ROOTPATH%\release\ -copy %QTPATH%\libgcc_s_dw2-1.dll %ROOTPATH%\release\ -copy %QTPATH%\libstdc++-6.dll %ROOTPATH%\release\ -copy %QTPATH%\libgcc_s_dw2-1.dll %ROOTPATH%\release\ -copy %QTPATH%\libwinpthread-1.dll %ROOTPATH%\release\ +copy %QTDIR%\5.8\mingw53_32\Qt5Charts.dll %ROOTPATH%\release\ +copy %QTDIR%\5.8\mingw53_32\Qt5Core.dll %ROOTPATH%\release\ +copy %QTDIR%\5.8\mingw53_32\Qt5Gui.dll %ROOTPATH%\release\ +copy %QTDIR%\5.8\mingw53_32\Qt5Network.dll %ROOTPATH%\release\ +copy %QTDIR%\5.8\mingw53_32\Qt5Widgets.dll %ROOTPATH%\release\ +copy %QTDIR%\5.8\mingw53_32\bin\libgcc_s_dw2-1.dll %ROOTPATH%\release\ +copy "%QTDIR%\5.8\mingw53_32\bin\libstdc++-6.dll" %ROOTPATH%\release\ +copy %QTDIR%\5.8\mingw53_32\bin\libwinpthread-1.dll %ROOTPATH%\release\ +copy %QTDIR%\5.8\mingw53_32\plugins\iconengines\qsvgicon.dll %ROOTPATH%\release\iconengines\qsvgicon.dll +copy %QTDIR%\5.8\mingw53_32\plugins\imageformats\qsvg.dll %ROOTPATH%\release\imageformats\qsvg.dll +copy %QTDIR%\5.8\mingw53_32\plugins\platforms\qwindows.dll %ROOTPATH%\release\platforms\qwindows.dll @if not "%RUNALL%"=="1" pause From 84e94c47ebab5840501ef40720f2e7fd46c9ac53 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Tue, 2 Jan 2018 17:48:23 -0800 Subject: [PATCH 161/166] Diagnosticsfix prepped for staging (#794) * PreviousBlockAge() chages in main.cpp/h * Diagnostics.cpp/h changes and bug fix * forgot ui --- src/main.cpp | 5 +- src/main.h | 1 + src/qt/diagnosticsdialog.cpp | 88 ++++++++++++++----------------- src/qt/diagnosticsdialog.h | 14 ++--- src/qt/forms/diagnosticsdialog.ui | 14 ++--- 5 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b43c592218..33360b07d8 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -162,7 +162,6 @@ std::string DefaultOrgKey(int key_length); double MintLimiter(double PORDiff,int64_t RSA_WEIGHT,std::string cpid,int64_t locktime); double GetLastPaymentTimeByCPID(std::string cpid); extern double CoinToDouble(double surrogate); -extern int64_t PreviousBlockAge(); void CheckForUpgrade(); int64_t GetRSAWeightByCPID(std::string cpid); extern MiningCPID GetMiningCPID(); @@ -397,11 +396,11 @@ bool PushGridcoinDiagnostics() std::string sBlock = mvApplicationCache["superblock;block_number"]; std::string sTimestamp = TimestampToHRDate(mvApplicationCacheTimestamp["superblock;magnitudes"]); printf("Pushing diagnostic data..."); - double lastblockage = PreviousBlockAge(); + std::string sLastBlockAge = ToString(PreviousBlockAge()); double PORDiff = GetDifficulty(GetLastBlockIndex(pindexBest, true)); std::string data = "" + sWhitelist + "" + cpiddata + "" + sAge + "" + consensus_hash + "" + sBlock + "" - + sTimestamp + "" + msPrimaryCPID + "" + ToString(lastblockage) + "" + RoundToString(PORDiff,2) + ""; + + sTimestamp + "" + msPrimaryCPID + "" + sLastBlockAge + "" + RoundToString(PORDiff,2) + ""; std::string testnet_flag = fTestNet ? "TESTNET" : "MAINNET"; qtExecuteGenericFunction("SetTestNetFlag",testnet_flag); double dResponse = qtPushGridcoinDiagnosticData(data); diff --git a/src/main.h b/src/main.h index 44365d733e..864bf22924 100755 --- a/src/main.h +++ b/src/main.h @@ -294,6 +294,7 @@ void ResendWalletTransactions(bool fForce = false); std::string DefaultWalletAddress(); +int64_t PreviousBlockAge(); /** (try to) add transaction to memory pool **/ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, diff --git a/src/qt/diagnosticsdialog.cpp b/src/qt/diagnosticsdialog.cpp index c829eaa991..4a0ecdb411 100644 --- a/src/qt/diagnosticsdialog.cpp +++ b/src/qt/diagnosticsdialog.cpp @@ -12,7 +12,6 @@ #include std::string GetListOf(std::string datatype); -double PreviousBlockAge(); DiagnosticsDialog::DiagnosticsDialog(QWidget *parent) : QDialog(parent), @@ -29,7 +28,7 @@ DiagnosticsDialog::~DiagnosticsDialog() delete ui; } -int DiagnosticsDialog::VarifyBoincPath() { +int DiagnosticsDialog::VerifyBoincPath() { boost::filesystem::path boincPath = (boost::filesystem::path) GetBoincDataDir(); if(boincPath.empty()) boincPath = (boost::filesystem::path) GetArgument("boincdatadir", ""); @@ -51,7 +50,7 @@ int DiagnosticsDialog::FindCPID() { return 0; } -int DiagnosticsDialog::VarifyIsCPIDValid() { +int DiagnosticsDialog::VerifyIsCPIDValid() { boost::filesystem::path clientStatePath = (boost::filesystem::path) GetBoincDataDir(); if(!clientStatePath.empty()) clientStatePath = clientStatePath / "client_state.xml"; @@ -96,20 +95,17 @@ int DiagnosticsDialog::VerifyCPIDIsInNeuralNetwork() { return 0; } -int DiagnosticsDialog::VarifyWalletIsSynced() { - std::string walletAgeString = ToString(PreviousBlockAge()); - long int walletAge = std::stoi(walletAgeString,nullptr,10); +int DiagnosticsDialog::VerifyWalletIsSynced() { + int64_t nwalletAge = PreviousBlockAge(); - if(walletAgeString.length() == 0) - return -1; - if(walletAge < (60 * 60)) + if(nwalletAge < (60 * 60)) return 1; else return 0; } -int DiagnosticsDialog::VarifyCPIDHasRAC() { +int DiagnosticsDialog::VerifyCPIDHasRAC() { boost::filesystem::path clientStatePath = (boost::filesystem::path) GetBoincDataDir(); if(!clientStatePath.empty()) clientStatePath = clientStatePath / "client_state.xml"; @@ -147,7 +143,7 @@ int DiagnosticsDialog::VarifyCPIDHasRAC() { } -int DiagnosticsDialog::VarifyAddNode() { +int DiagnosticsDialog::VerifyAddNode() { long int peersLength = boost::filesystem::file_size(GetDataDir(true) / "peers.dat"); std::string addNode = GetArgument("addnode", ""); @@ -163,7 +159,7 @@ int DiagnosticsDialog::VarifyAddNode() { } -void DiagnosticsDialog::VarifyClock() { +void DiagnosticsDialog::VerifyClock() { QHostInfo info = QHostInfo::fromName("pool.ntp.org"); udpSocket = new QUdpSocket(this); @@ -180,7 +176,7 @@ void DiagnosticsDialog::VarifyClock() { -void DiagnosticsDialog::VarifyTCPPort() { +void DiagnosticsDialog::VerifyTCPPort() { tcpSocket = new QTcpSocket(this); connect(tcpSocket, SIGNAL(connected()), this, SLOT(TCPFinished())); @@ -195,7 +191,7 @@ void DiagnosticsDialog::on_testBtn_clicked() { //boinc path ui->boincPathResultLbl->setText("Testing..."); this->repaint(); - result = DiagnosticsDialog::VarifyBoincPath(); + result = DiagnosticsDialog::VerifyBoincPath(); if(result == 1) ui->boincPathResultLbl->setText("Passed"); else @@ -209,63 +205,61 @@ void DiagnosticsDialog::on_testBtn_clicked() { else ui->findCPIDReaultLbl->setText("Failed (Is CPID in gridcoinresearch.conf?)"); //cpid valid - ui->varifyCPIDValidResultLbl->setText("Testing..."); + ui->verifyCPIDValidResultLbl->setText("Testing..."); this->repaint(); - result = DiagnosticsDialog::VarifyIsCPIDValid(); + result = DiagnosticsDialog::VerifyIsCPIDValid(); if(result == 1) - ui->varifyCPIDValidResultLbl->setText("Passed"); + ui->verifyCPIDValidResultLbl->setText("Passed"); else - ui->varifyCPIDValidResultLbl->setText("Failed (BOINC CPID and gridcoinresearch.conf CPID do not match)"); + ui->verifyCPIDValidResultLbl->setText("Failed (BOINC CPID and gridcoinresearch.conf CPID do not match)"); //cpid has rac - ui->varifyCPIDHasRACResultLbl->setText("Testing..."); + ui->verifyCPIDHasRACResultLbl->setText("Testing..."); this->repaint(); - result = DiagnosticsDialog::VarifyCPIDHasRAC(); + result = DiagnosticsDialog::VerifyCPIDHasRAC(); if(result > 0) - ui->varifyCPIDHasRACResultLbl->setText(QString::fromStdString("Passed RAC: " + std::to_string(result))); + ui->verifyCPIDHasRACResultLbl->setText(QString::fromStdString("Passed RAC: " + std::to_string(result))); else - ui->varifyCPIDHasRACResultLbl->setText("Failed"); + ui->verifyCPIDHasRACResultLbl->setText("Failed"); //cpid is in nn - ui->varifyCPIDIsInNNResultLbl->setText("Testing..."); + ui->verifyCPIDIsInNNResultLbl->setText("Testing..."); this->repaint(); result = DiagnosticsDialog::VerifyCPIDIsInNeuralNetwork(); if(result == 1) - ui->varifyCPIDIsInNNResultLbl->setText("Passed"); + ui->verifyCPIDIsInNNResultLbl->setText("Passed"); else if (result == -1) - ui->varifyCPIDIsInNNResultLbl->setText("Beacon data empty, sync wallet"); + ui->verifyCPIDIsInNNResultLbl->setText("Beacon data empty, sync wallet"); else - ui->varifyCPIDIsInNNResultLbl->setText("Failed"); + ui->verifyCPIDIsInNNResultLbl->setText("Failed"); //wallet synced - ui->varifyWalletIsSyncedResultLbl->setText("Testing..."); + ui->verifyWalletIsSyncedResultLbl->setText("Testing..."); this->repaint(); - result = DiagnosticsDialog::VarifyWalletIsSynced(); + result = DiagnosticsDialog::VerifyWalletIsSynced(); if(result == 1) - ui->varifyWalletIsSyncedResultLbl->setText("Passed"); - else if (result == -1) - ui->varifyWalletIsSyncedResultLbl->setText("Sync data empty"); + ui->verifyWalletIsSyncedResultLbl->setText("Passed"); else - ui->varifyWalletIsSyncedResultLbl->setText("Failed"); + ui->verifyWalletIsSyncedResultLbl->setText("Failed"); //clock - ui->varifyClkResultLbl->setText("Testing..."); + ui->verifyClkResultLbl->setText("Testing..."); this->repaint(); - DiagnosticsDialog::VarifyClock(); + DiagnosticsDialog::VerifyClock(); //addnode - ui->varifyAddnodeResultLbl->setText("Testing..."); + ui->verifyAddnodeResultLbl->setText("Testing..."); this->repaint(); - result = DiagnosticsDialog::VarifyAddNode(); + result = DiagnosticsDialog::VerifyAddNode(); if(result == 1) - ui->varifyAddnodeResultLbl->setText("Passed"); + ui->verifyAddnodeResultLbl->setText("Passed"); else if(result == 2) - ui->varifyAddnodeResultLbl->setText("Passed (Addnode does not exist but peers are synced)"); + ui->verifyAddnodeResultLbl->setText("Passed (Addnode does not exist but peers are synced)"); else if(result == 3) - ui->varifyAddnodeResultLbl->setText("Passed (Addnode exists but peers not synced)"); + ui->verifyAddnodeResultLbl->setText("Passed (Addnode exists but peers not synced)"); else if(result == -1) - ui->varifyAddnodeResultLbl->setText("Failed (Please add addnode=node.gridcoin.us in conf file)"); + ui->verifyAddnodeResultLbl->setText("Failed (Please add addnode=node.gridcoin.us in conf file)"); else - ui->varifyAddnodeResultLbl->setText("Failed"); + ui->verifyAddnodeResultLbl->setText("Failed"); //tcp port - ui->varifyTCPPortResultLbl->setText("Testing..."); + ui->verifyTCPPortResultLbl->setText("Testing..."); this->repaint(); - DiagnosticsDialog::VarifyTCPPort(); + DiagnosticsDialog::VerifyTCPPort(); //client version ui->checkClientVersionResultLbl->setText("Testing..."); networkManager->get(QNetworkRequest(QUrl("https://api.github.com/repos/gridcoin/Gridcoin-Research/releases/latest"))); @@ -294,21 +288,21 @@ void DiagnosticsDialog::clkFinished() { boost::posix_time::time_duration timeDiff = networkTime - localTime; if(timeDiff.minutes() < 3) - ui->varifyClkResultLbl->setText("Passed"); + ui->verifyClkResultLbl->setText("Passed"); else - ui->varifyClkResultLbl->setText("Failed (Sync local time with network)"); + ui->verifyClkResultLbl->setText("Failed (Sync local time with network)"); this->repaint(); } void DiagnosticsDialog::TCPFinished() { tcpSocket->close(); - ui->varifyTCPPortResultLbl->setText("Passed"); + ui->verifyTCPPortResultLbl->setText("Passed"); this->repaint(); } void DiagnosticsDialog::TCPFailed(QAbstractSocket::SocketError socket) { - ui->varifyTCPPortResultLbl->setText("Failed (Port 32749 may be blocked by your firewall)"); + ui->verifyTCPPortResultLbl->setText("Failed (Port 32749 may be blocked by your firewall)"); this->repaint(); } diff --git a/src/qt/diagnosticsdialog.h b/src/qt/diagnosticsdialog.h index ba8e87f675..06d05c0d14 100644 --- a/src/qt/diagnosticsdialog.h +++ b/src/qt/diagnosticsdialog.h @@ -21,15 +21,15 @@ class DiagnosticsDialog : public QDialog private: Ui::DiagnosticsDialog *ui; void GetData(); - int VarifyBoincPath(); + int VerifyBoincPath(); int VerifyCPIDIsInNeuralNetwork(); - int VarifyWalletIsSynced(); - int VarifyCPIDHasRAC(); - int VarifyAddNode(); - int VarifyIsCPIDValid(); + int VerifyWalletIsSynced(); + int VerifyCPIDHasRAC(); + int VerifyAddNode(); + int VerifyIsCPIDValid(); int FindCPID(); - void VarifyClock(); - void VarifyTCPPort(); + void VerifyClock(); + void VerifyTCPPort(); double GetTotalCPIDRAC(std::string cpid); double GetUserRAC(std::string cpid, int *projects); std::string KeyValue(std::string key); diff --git a/src/qt/forms/diagnosticsdialog.ui b/src/qt/forms/diagnosticsdialog.ui index 1a3f526066..70e005b412 100644 --- a/src/qt/forms/diagnosticsdialog.ui +++ b/src/qt/forms/diagnosticsdialog.ui @@ -69,7 +69,7 @@ - + 0 @@ -127,7 +127,7 @@ - + 0 @@ -185,7 +185,7 @@ - + 0 @@ -226,7 +226,7 @@ - + 0 @@ -255,7 +255,7 @@ - + 0 @@ -284,7 +284,7 @@ - + 0 @@ -313,7 +313,7 @@ - + 0 From 68b0fa5c5621d51f732dbc8d963d22fb8543021a Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Wed, 3 Jan 2018 11:24:20 +0100 Subject: [PATCH 162/166] Make auto upgrades opt in. Change wallet checks to be time based instead of height based. This removes the need for checking if projects are initialized and it takes block sync states out of the equation. All (Windows) wallet will now check for updates once per day. If the user has enabled auto upgrades through the "autoupgrade" config option the upgrade will be downloaded and applied. --- src/global_objects_noui.hpp | 2 -- src/main.cpp | 35 +++++++++++++++++++---------------- src/qt/bitcoingui.cpp | 27 ++++++++++++--------------- 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/global_objects_noui.hpp b/src/global_objects_noui.hpp index e9dfe2af48..cbd1f57e7c 100755 --- a/src/global_objects_noui.hpp +++ b/src/global_objects_noui.hpp @@ -11,8 +11,6 @@ extern bool bCPIDsLoaded; extern bool bProjectsInitialized; extern bool bNetAveragesLoaded; extern bool bForceUpdate; -extern bool bCheckedForUpgrade; -extern bool bCheckedForUpgradeLive; extern bool bGlobalcomInitialized; extern bool bGridcoinGUILoaded; diff --git a/src/main.cpp b/src/main.cpp index 33360b07d8..27db3ee6bb 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,7 +85,7 @@ extern bool LoadAdminMessages(bool bFullTableScan,std::string& out_errors); extern bool UnusualActivityReport(); extern std::string GetCurrentNeuralNetworkSupermajorityHash(double& out_popularity); - + extern double CalculatedMagnitude2(std::string cpid, int64_t locktime,bool bUseLederstrumpf); @@ -162,13 +162,15 @@ std::string DefaultOrgKey(int key_length); double MintLimiter(double PORDiff,int64_t RSA_WEIGHT,std::string cpid,int64_t locktime); double GetLastPaymentTimeByCPID(std::string cpid); extern double CoinToDouble(double surrogate); -void CheckForUpgrade(); +bool IsUpgradeAvailable(); +int UpgradeClient(); int64_t GetRSAWeightByCPID(std::string cpid); extern MiningCPID GetMiningCPID(); extern StructCPID GetStructCPID(); int64_t nLastBlockSolved = 0; //Future timestamp int64_t nLastBlockSubmitted = 0; +int64_t nLastCheckedForUpdate = 0; ///////////////////////MINOR VERSION//////////////////////////////// std::string msMasterProjectPublicKey = "049ac003b3318d9fe28b2830f6a95a2624ce2a69fb0c0c7ac0b513efcc1e93a6a6e8eba84481155dd82f2f1104e0ff62c69d662b0094639b7106abc5d84f948c0a"; @@ -251,8 +253,6 @@ extern std::string aes_complex_hash(uint256 scrypt_hash); bool bNetAveragesLoaded = false; bool bTallyStarted_retired = false; bool bForceUpdate = false; -bool bCheckedForUpgrade = false; -bool bCheckedForUpgradeLive = false; bool bGlobalcomInitialized = false; bool bStakeMinerOutOfSyncWithNetwork = false; volatile bool bDoTally_retired = false; @@ -4436,23 +4436,26 @@ void GridcoinServices() if (TimerMain("gather_cpids",480)) msNeuralResponse.clear(); - if (TimerMain("check_for_autoupgrade",240)) +#ifdef QT_GUI + // Check for updates once per day. + if(GetAdjustedTime() - nLastCheckedForUpdate > 24 * 60 * 60) { - if (fDebug3) printf("Checking for upgrade..."); - bCheckedForUpgradeLive = true; - } + nLastCheckedForUpdate = GetAdjustedTime(); - #if defined(WIN32) && defined(QT_GUI) - if (bCheckedForUpgradeLive && !fTestNet && bProjectsInitialized && bGlobalcomInitialized) + if (fDebug3) printf("Checking for upgrade..."); + if(IsUpgradeAvailable()) { - bCheckedForUpgradeLive=false; - printf("{Checking for Upgrade} "); - CheckForUpgrade(); - printf("{Done checking for upgrade} "); + printf("Upgrade available."); + if(GetArgument("autoupgrade", "false") == "true") + { + printf("Upgrading client."); + UpgradeClient(); + } } - #endif - if (fDebug10) printf(" {/SVC} "); + } +#endif + if (fDebug10) printf(" {/SVC} "); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 5353cc87e4..faea561e2b 100755 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -129,9 +129,6 @@ extern int CreateRestorePoint(); extern int DownloadBlocks(); void GetGlobalStatus(); -extern int UpgradeClient(); -extern void CheckForUpgrade(); - bool IsConfigFileEmpty(); void HarvestCPIDs(bool cleardata); extern int RestartClient(); @@ -471,20 +468,20 @@ void qtSetSessionInfo(std::string defaultgrcaddress, std::string cpid, double ma #endif } -void CheckForUpgrade() +bool IsUpgradeAvailable() { - if (!bGlobalcomInitialized) return; + if (!bGlobalcomInitialized) + return false; - if (bCheckedForUpgrade == false && !fTestNet && bProjectsInitialized) - { - int nNeedsUpgrade = 0; - bCheckedForUpgrade = true; - #ifdef WIN32 - nNeedsUpgrade = globalcom->dynamicCall("ClientNeedsUpgrade()").toInt(); - #endif - printf("Needs upgraded %f\r\n",(double)nNeedsUpgrade); - if (nNeedsUpgrade) UpgradeClient(); - } + bool upgradeAvailable = false; + if (!fTestNet) + { +#ifdef WIN32 + upgradeAvailable = globalcom->dynamicCall("ClientNeedsUpgrade()").toInt(); +#endif + } + + return upgradeAvailable; } From 65132b531f4b505bf691bda7e0c0cac47b01f149 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Thu, 4 Jan 2018 06:23:09 +0100 Subject: [PATCH 163/166] Change QVariant cast check. --- src/qt/overviewpage.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 58d562f67d..ab0f5f5cc6 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -57,14 +57,9 @@ class TxViewDelegate : public QAbstractItemDelegate qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong(); bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool(); - - //QColor foreground = option.palette.color(QPalette::Text); - //R Halford: 11-28-2013: QColor foreground = QColor(200, 0, 0); - QVariant value = index.data(Qt::ForegroundRole); - //QColor foreground = option.palette.color(QPalette::Text); - if(value.canConvert(QMetaType::QColor)) + if(value.canConvert()) { foreground = qvariant_cast(value); } From 14c5880ab357367b9bcc16c83922ea14796f3cdf Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Fri, 5 Jan 2018 07:07:00 +0100 Subject: [PATCH 164/166] Fix boost-1.66 incompatibilities. --- src/bitcoinrpc.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 60d17dee3e..1eb6348f5b 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -703,8 +703,8 @@ void ThreadRPCServer(void* parg) } // Forward declaration required for RPCListen -template -static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, ssl::context& context, bool fUseSSL, AcceptedConnection* conn, @@ -713,8 +713,8 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor -static void RPCListen(boost::shared_ptr< basic_socket_acceptor > acceptor, +template +static void RPCListen(boost::shared_ptr< basic_socket_acceptor > acceptor, ssl::context& context, const bool fUseSSL) { @@ -724,7 +724,7 @@ static void RPCListen(boost::shared_ptr< basic_socket_acceptorasync_accept( conn->sslStream.lowest_layer(), conn->peer, - boost::bind(&RPCAcceptHandler, + boost::bind(&RPCAcceptHandler, acceptor, boost::ref(context), fUseSSL, @@ -735,8 +735,8 @@ static void RPCListen(boost::shared_ptr< basic_socket_acceptor -static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, ssl::context& context, const bool fUseSSL, AcceptedConnection* conn, @@ -813,7 +813,7 @@ void ThreadRPCServer2(void* parg) assert(rpc_io_service == NULL); rpc_io_service = new asio::io_service(); - ssl::context context(*rpc_io_service, ssl::context::sslv23); + ssl::context context(ssl::context::sslv23); if (fUseSSL) { context.set_options(ssl::context::no_sslv2); @@ -829,7 +829,7 @@ void ThreadRPCServer2(void* parg) else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str()); string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"); - SSL_CTX_set_cipher_list(context.impl(), strCiphers.c_str()); + SSL_CTX_set_cipher_list(context.native_handle(), strCiphers.c_str()); } // Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets @@ -1125,7 +1125,7 @@ Object CallRPC(const string& strMethod, const Array& params) // Connect to localhost bool fUseSSL = GetBoolArg("-rpcssl"); asio::io_service io_service; - ssl::context context(io_service, ssl::context::sslv23); + ssl::context context(ssl::context::sslv23); context.set_options(ssl::context::no_sslv2); asio::ssl::stream sslStream(io_service, context); SSLIOStreamDevice d(sslStream, fUseSSL); From 855f45221a8391dd4bded06d80b7e9de48289995 Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 8 Jan 2018 10:32:29 +0100 Subject: [PATCH 165/166] Update changelog. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3469ffe250..3d8dc3078c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). Missing rewards will be reimbursed, #552 (@Foggyx420). - Fix minor UI typos, #661 (@Erkan-Yilmaz). - Fix stake modifier, #686 (@tomasbrod). + - Improve boost-1.66.0 compatibility, #800 (@denravonska). + - Fix crash in diagnostics dialog, #794 (@Foggyx420). ### Changed - Changed versioning extraction from git. Test builds can no longer be used to @@ -45,6 +47,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix voting sorting issues, #610 (@MagixInTheAir). - Improve wallet backup, #610 (@Foggyx420). - Update seed nodes, #783 (@barton2526). + - Auto upgrades are now opt-in via the "autoupgrade" flag, #796 (@denravonska). + - Clean up seed nodes, #783 (@barton2526). ### Removed - Remove CSV exporter which used unreliable data, #759 (@denravonska). From a23ec597a14ce25b1002b587c3177c3628caf00d Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Mon, 8 Jan 2018 20:57:38 +0100 Subject: [PATCH 166/166] Set v9 to start on block 1144000 in production. --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index 864bf22924..ed433f841d 100755 --- a/src/main.h +++ b/src/main.h @@ -100,7 +100,7 @@ inline uint32_t IsV9Enabled(int nHeight) { return fTestNet ? nHeight >= 399000 - : nHeight >= 2000000; + : nHeight >= 1144000; } inline int GetSuperblockAgeSpacing(int nHeight)