diff --git a/src/gridcoin/researcher.cpp b/src/gridcoin/researcher.cpp index 10834da679..7871e0c48f 100644 --- a/src/gridcoin/researcher.cpp +++ b/src/gridcoin/researcher.cpp @@ -401,7 +401,7 @@ std::optional FallbackToCpidByEmail( //! \param projects Map of local projects loaded from BOINC's client_state.xml //! file. //! -bool DetectSplitCpid(const MiningProjectMap& projects) +ResearcherCpidErrorStatus DetectSplitCpid(const MiningProjectMap& projects) { std::unordered_map eligible_cpids; bool mismatched_email = false; @@ -418,7 +418,14 @@ bool DetectSplitCpid(const MiningProjectMap& projects) } } - if (mismatched_email || eligible_cpids.size() > 1) { + if (mismatched_email && eligible_cpids.size() == 1) { + LogPrintf("WARN: %s: Detected email mismatch between email specified in config file and BOINC project " + "registration."); + + return ResearcherCpidErrorStatus::MISMATCHED_EMAIL; + } + + if (eligible_cpids.size() > 1) { std::string warning = "WARNING: Detected potential CPID split. "; warning += "Eligible CPIDs: \n"; @@ -429,10 +436,10 @@ bool DetectSplitCpid(const MiningProjectMap& projects) LogPrintf("%s", warning); - return true; + return ResearcherCpidErrorStatus::SPLIT_CPID; } - return false; + return ResearcherCpidErrorStatus::NONE; } //! @@ -1056,12 +1063,12 @@ Researcher::Researcher( MiningId mining_id, MiningProjectMap projects, const GRC::BeaconError beacon_error, - const bool has_split_cpid + const ResearcherCpidErrorStatus cpid_error_status ) : m_mining_id(std::move(mining_id)) , m_projects(std::move(projects)) , m_beacon_error(beacon_error) - , m_has_split_cpid(has_split_cpid) + , m_cpid_error_status(cpid_error_status) { } @@ -1217,17 +1224,17 @@ void Researcher::Reload(MiningProjectMap projects, GRC::BeaconError beacon_error } } - bool has_split_cpid = false; + ResearcherCpidErrorStatus cpid_error_status; if (const CpidOption cpid = mining_id.TryCpid()) { - has_split_cpid = DetectSplitCpid(projects); + cpid_error_status = DetectSplitCpid(projects); LogPrintf("Selected primary CPID: %s", cpid->ToString()); } else if (!projects.empty()) { LogPrintf("WARNING: no projects eligible for research rewards."); } StoreResearcher( - Researcher(std::move(mining_id), std::move(projects), beacon_error, has_split_cpid)); + Researcher(std::move(mining_id), std::move(projects), beacon_error, cpid_error_status)); } void Researcher::Refresh() @@ -1375,9 +1382,9 @@ GRC::BeaconError Researcher::BeaconError() const return m_beacon_error; } -bool Researcher::hasSplitCpid() const +ResearcherCpidErrorStatus Researcher::hasSplitCpid() const { - return m_has_split_cpid; + return m_cpid_error_status; } bool Researcher::ChangeMode(const ResearcherMode mode, std::string email) diff --git a/src/gridcoin/researcher.h b/src/gridcoin/researcher.h index e4a7d5b293..a8d22b6104 100644 --- a/src/gridcoin/researcher.h +++ b/src/gridcoin/researcher.h @@ -48,6 +48,13 @@ enum class ResearcherStatus NO_BEACON, //!< No active beacon public key advertised. }; +enum class ResearcherCpidErrorStatus +{ + NONE, //!< No error + MISMATCHED_EMAIL, //!< Email specified in config file is likely mismatched with BOINC projects + SPLIT_CPID, //!< More than one cpid encountered across active projects +}; + //! //! \brief Represents a Gridcoin pool that stakes on behalf of its users. //! @@ -389,11 +396,10 @@ class Researcher //! \param beacon_error Last beacon advertisement error, if any. //! \param has_split_cpid Existence of split cpid. //! - Researcher( - MiningId mining_id, + Researcher(MiningId mining_id, MiningProjectMap projects, const BeaconError beacon_error = GRC::BeaconError::NONE, - bool has_split_cpid = false); + ResearcherCpidErrorStatus researcher_error_status = ResearcherCpidErrorStatus::NONE); //! //! \brief Set up the local researcher context. @@ -580,11 +586,11 @@ class Researcher GRC::BeaconError BeaconError() const; //! - //! \brief Returns true if a split CPID situation exists (i.e. project list + //! \brief Returns error status related to email mismatch or split CPID situation (i.e. project list //! refers to more than one CPID). - //! \return boolean of split cpid existence + //! \return enum providing error status of cpid for researcher //! - bool hasSplitCpid() const; + ResearcherCpidErrorStatus hasSplitCpid() const; //! //! \brief Update how a user prefers to participate in the research reward @@ -643,10 +649,10 @@ class Researcher AdvertiseBeaconResult RevokeBeacon(const Cpid cpid); private: - MiningId m_mining_id; //!< CPID or INVESTOR variant. - MiningProjectMap m_projects; //!< Local projects loaded from BOINC. - GRC::BeaconError m_beacon_error; //!< Last beacon error that occurred, if any. - bool m_has_split_cpid; //!< Flag that indicates project list has more than one CPID + MiningId m_mining_id; //!< CPID or INVESTOR variant. + MiningProjectMap m_projects; //!< Local projects loaded from BOINC. + GRC::BeaconError m_beacon_error; //!< Last beacon error that occurred, if any. + ResearcherCpidErrorStatus m_cpid_error_status; //!< Enum that indicates project list email mismatch or more than one CPID }; // Researcher } diff --git a/src/qt/researcher/researchermodel.cpp b/src/qt/researcher/researchermodel.cpp index d5d8e07326..6475575e77 100644 --- a/src/qt/researcher/researchermodel.cpp +++ b/src/qt/researcher/researchermodel.cpp @@ -186,10 +186,10 @@ void ResearcherModel::showWizard(WalletModel* wallet_model) wizard->setStartId(ResearcherWizard::PageInvestor); } else if (detectedPoolMode()) { wizard->setStartId(ResearcherWizard::PagePoolSummary); - } else if (hasSplitCpid()) { - // If there is a split CPID situation, then the actionNeeded is also set, but - // in the case of a split CPID we want to go to the PageSummary screen, where they - // will see the warning for the split CPID. This is more important than renewing the beacon + } else if (hasSplitCpid() > ResearcherCpidErrorStatus::NONE) { + // If there is a split CPID/email mismatch situation, then the actionNeeded is also set, but + // in this case we want to go to the PageSummary screen, where they will see the warning for + // the email mismatch or split CPID. This is more important than renewing the beacon wizard->setStartId(ResearcherWizard::PageSummary); } else if (hasRenewableBeacon()) { wizard->setStartId(ResearcherWizard::PageBeacon); @@ -240,7 +240,7 @@ bool ResearcherModel::actionNeeded() const } if (hasEligibleProjects()) { - return hasSplitCpid() || (!hasActiveBeacon() && !hasPendingBeacon()); + return hasSplitCpid() > ResearcherCpidErrorStatus::NONE || (!hasActiveBeacon() && !hasPendingBeacon()); } return !hasPoolProjects(); @@ -281,7 +281,7 @@ bool ResearcherModel::hasRAC() const return m_researcher->HasRAC(); } -bool ResearcherModel::hasSplitCpid() const +ResearcherCpidErrorStatus ResearcherModel::hasSplitCpid() const { return m_researcher->hasSplitCpid(); } diff --git a/src/qt/researcher/researchermodel.h b/src/qt/researcher/researchermodel.h index 36dfc43fb9..744f1db4a6 100644 --- a/src/qt/researcher/researchermodel.h +++ b/src/qt/researcher/researchermodel.h @@ -19,6 +19,8 @@ namespace GRC { class Beacon; class Researcher; +enum class ResearcherCpidErrorStatus; + //! //! \brief A smart pointer around the global BOINC researcher context. //! @@ -94,7 +96,7 @@ class ResearcherModel : public QObject bool hasRenewableBeacon() const; bool hasMagnitude() const; bool hasRAC() const; - bool hasSplitCpid() const; + GRC::ResearcherCpidErrorStatus hasSplitCpid() const; bool needsBeaconAuth() const; QString email() const; @@ -122,7 +124,7 @@ class ResearcherModel : public QObject bool m_configured_for_investor_mode; bool m_wizard_open; bool m_out_of_sync; - bool m_split_cpid; + bool m_cpid_error_status; bool m_privacy_enabled; QString m_theme_suffix; diff --git a/src/qt/researcher/researcherwizardsummarypage.cpp b/src/qt/researcher/researcherwizardsummarypage.cpp index e84b268731..499f010b87 100644 --- a/src/qt/researcher/researcherwizardsummarypage.cpp +++ b/src/qt/researcher/researcherwizardsummarypage.cpp @@ -9,6 +9,8 @@ #include "qt/researcher/researchermodel.h" #include "qt/researcher/researcherwizardsummarypage.h" +#include "gridcoin/researcher.h" + // ----------------------------------------------------------------------------- // Class: ResearcherWizardSummaryPage // ----------------------------------------------------------------------------- @@ -128,11 +130,17 @@ void ResearcherWizardSummaryPage::refreshOverallStatus() } else if (!m_researcher_model->hasMagnitude()) { status = tr("Waiting for magnitude."); icon = QIcon(":/icons/scraper_waiting_light"); - } else if (m_researcher_model->hasSplitCpid()) { + } else if (m_researcher_model->hasSplitCpid() == GRC::ResearcherCpidErrorStatus::MISMATCHED_EMAIL) { + status = tr("Email mismatch - your projects all are linked to the same CPID but the email does\n" + "not match what is configured here in the client. Please ensure that the email used\n" + "here matches that used for your BOINC projects."); + icon = QIcon(":/icons/warning"); + } else if (m_researcher_model->hasSplitCpid() == GRC::ResearcherCpidErrorStatus::SPLIT_CPID) { status = tr("Likely split CPID - projects refer to more than one CPID. Please ensure all\n" - "of your projects are attached using the same email address and if you added\n" - "a project recently, update that project and then all other projects using the\n" - "update button in the BOINC manager, then go to the projects tab and refresh."); + "of your projects are attached using the same email address, that this email\n" + "is the same as you used here in the Gridcoin client, and if you added a project\n" + "recently, update that project and then all other projects using the update\n" + "button in the BOINC manager, then go to the projects tab and refresh."); icon = QIcon(":/icons/warning"); } else { status = tr("Everything looks good.");