Skip to content

Commit dca0a8d

Browse files
committed
Refactor beaconstatus to separate actual back-end
calls into GetBeaconStatus so that this can be consumed easily by the GUI. Implement simple BeaconStatus struct. Implement initial BitcoinGUI::updateBeaconIcon() function.
1 parent 7fa60e5 commit dca0a8d

File tree

9 files changed

+174
-50
lines changed

9 files changed

+174
-50
lines changed

src/Makefile.qt.include

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,9 +284,9 @@ RES_ICONS = \
284284
qt/res/icons/tx_por_ss.svg \
285285
qt/res/icons/tx_por.svg \
286286
qt/res/icons/tx2.png \
287+
qt/res/icons/white_and_red_x.svg \
287288
qt/res/icons/www.png \
288289
qt/res/icons/wwww.png \
289-
qt/res/icons/x.svg \
290290
qt/res/icons/icons_native/overview.svg \
291291
qt/res/icons/icons_light/overview.svg \
292292
qt/res/icons/icons_dark/overview.svg \

src/beacon.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include "appcache.h"
99
#include "contract/contract.h"
1010
#include "key.h"
11+
#include "neuralnet/researcher.h"
12+
#include "neuralnet/tally.h"
1113

1214
std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxSeconds);
1315
std::string ExtractXML(const std::string& XMLdata, const std::string& key, const std::string& key_end);
@@ -316,3 +318,25 @@ BeaconConsensus GetConsensusBeaconList()
316318

317319
return Consensus;
318320
}
321+
322+
// -------------------------- Both In and Out
323+
BeaconStatus GetBeaconStatus(std::string& sCPID)
324+
{
325+
BeaconStatus beacon_status;
326+
327+
LOCK(cs_main);
328+
329+
if (sCPID.empty())
330+
{
331+
sCPID = NN::GetPrimaryCpid();
332+
}
333+
334+
beacon_status.sPubKey = GetBeaconPublicKey(sCPID, false);
335+
beacon_status.iBeaconTimestamp = BeaconTimeStamp(sCPID);
336+
beacon_status.timestamp = TimestampToHRDate(beacon_status.iBeaconTimestamp);
337+
beacon_status.hasBeacon = HasActiveBeacon(sCPID);
338+
beacon_status.dPriorSBMagnitude = NN::Tally::GetMagnitude(NN::MiningId::Parse(sCPID));
339+
beacon_status.is_mine = (sCPID == NN::GetPrimaryCpid());
340+
341+
return beacon_status;
342+
}

src/beacon.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ struct BeaconConsensus
2525
BeaconMap mBeaconMap;
2626
};
2727

28+
//Note this should be replaced when we redo the beacon structures...
29+
struct BeaconStatus
30+
{
31+
std::string sPubKey;
32+
int64_t iBeaconTimestamp;
33+
std::string timestamp;
34+
bool hasBeacon;
35+
double dPriorSBMagnitude;
36+
bool is_mine;
37+
};
38+
2839
//!
2940
//! \brief Generate beacon key pair.
3041
//!
@@ -100,3 +111,10 @@ bool ImportBeaconKeysFromConfig(const std::string& cpid, CWallet* wallet);
100111
//! \return A list of active beacons.
101112
//!
102113
BeaconConsensus GetConsensusBeaconList();
114+
115+
//!
116+
//! \brief Get beacon status for a specified CPID.
117+
//!
118+
//! \return Beacon status structure for specific CPID.
119+
//!
120+
BeaconStatus GetBeaconStatus(std::string& sCPID);

src/neuralnet/researcher.cpp

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,6 @@ std::string LowerUnderscore(std::string data)
4444
return data;
4545
}
4646

47-
//!
48-
//! \brief Determine whether the wallet must run in investor mode before trying
49-
//! to load BOINC CPIDs.
50-
//!
51-
//! \return \c true if the user explicitly configured investor mode or failed
52-
//! to input a valid email address.
53-
//!
54-
bool ConfiguredForInvestorMode()
55-
{
56-
if (GetBoolArg("-investor", false)) {
57-
LogPrintf("Investor mode configured. Skipping CPID import.");
58-
return true;
59-
}
60-
61-
if (Researcher::Email().empty()) {
62-
LogPrintf(
63-
"WARNING: Please set 'email=<your BOINC account email>' in "
64-
"gridcoinresearch.conf. Continuing in investor mode.");
65-
66-
return true;
67-
}
68-
69-
return false;
70-
}
71-
7247
//!
7348
//! \brief Fetch the contents of BOINC's client_state.xml file from disk.
7449
//!
@@ -507,14 +482,32 @@ std::string Researcher::Email()
507482
return email;
508483
}
509484

485+
bool Researcher::ConfiguredForInvestorMode(bool log)
486+
{
487+
if (GetBoolArg("-investor", false)) {
488+
if (log) LogPrintf("Investor mode configured. Skipping CPID import.");
489+
return true;
490+
}
491+
492+
if (Researcher::Email().empty()) {
493+
if (log) LogPrintf(
494+
"WARNING: Please set 'email=<your BOINC account email>' in "
495+
"gridcoinresearch.conf. Continuing in investor mode.");
496+
497+
return true;
498+
}
499+
500+
return false;
501+
}
502+
510503
ResearcherPtr Researcher::Get()
511504
{
512505
return std::atomic_load(&researcher);
513506
}
514507

515508
void Researcher::Reload()
516509
{
517-
if (ConfiguredForInvestorMode()) {
510+
if (ConfiguredForInvestorMode(true)) {
518511
StoreResearcher(Researcher()); // Investor
519512
return;
520513
}

src/neuralnet/researcher.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,15 @@ class Researcher
220220
//!
221221
static std::string Email();
222222

223+
//!
224+
//! \brief Determine whether the wallet must run in investor mode before trying
225+
//! to load BOINC CPIDs.
226+
//!
227+
//! \return \c true if the user explicitly configured investor mode or failed
228+
//! to input a valid email address.
229+
//!
230+
static bool ConfiguredForInvestorMode(bool log = false);
231+
223232
//!
224233
//! \brief Get the current global researcher context.
225234
//!

src/qt/bitcoin.qrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@
6969
<file alias="connect_3">res/icons/connect3.svg</file>
7070
<file alias="connect_4">res/icons/connect4.svg</file>
7171
<file alias="notsynced">res/icons/notsynced.svg</file>
72-
<file alias="white_and_red_x">res/icons/x.svg</file>
7372
<file alias="synced">res/icons/green_check.svg</file>
73+
<file alias="white_and_red_x">res/icons/white_and_red_x.svg</file>
7474
</qresource>
7575
<qresource prefix="/images">
7676
<file alias="splash">res/images/splash3.png</file>

src/qt/bitcoingui.cpp

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#include "contract/polls.h"
8585
#include "contract/contract.h"
8686
#include "neuralnet/researcher.h"
87+
#include "beacon.h"
8788

8889
#include <iostream>
8990
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
@@ -1620,14 +1621,99 @@ void BitcoinGUI::updateScraperIcon(int scraperEventtype, int status)
16201621
else if ((scraperEventtype == (int)scrapereventtypes::Convergence || scraperEventtype == (int)scrapereventtypes::SBContract)
16211622
&& status == CT_DELETED)
16221623
{
1623-
labelScraperIcon->setPixmap(QIcon(":/icons/red_and_white_x").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1624+
labelScraperIcon->setPixmap(QIcon(":/icons/white_and_red_x").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
16241625
labelScraperIcon->setToolTip(tr("Scraper: No convergence able to be achieved. Will retry in a few minutes."));
16251626
}
16261627

16271628
}
16281629

16291630
void BitcoinGUI::updateBeaconIcon()
16301631
{
1631-
labelBeaconIcon->setPixmap(QIcon(":/icons/beacon_green").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1632-
labelBeaconIcon->setToolTip(tr("Iconsize = %1.").arg(QString(std::to_string(STATUSBAR_ICONSIZE).c_str())));
1632+
std::string sCPID;
1633+
double beacon_age = 0;
1634+
double time_to_expiration = 0;
1635+
double advertise_threshold = 0;
1636+
1637+
BeaconStatus beacon_status = GetBeaconStatus(sCPID);
1638+
1639+
// Intent is to be an investor. Suppress icon.
1640+
if (NN::Researcher::ConfiguredForInvestorMode())
1641+
{
1642+
labelBeaconIcon->hide();
1643+
}
1644+
// Not configured for investor mode, which means the intent is to be a researcher.
1645+
else
1646+
{
1647+
// Beacon does not exist.
1648+
if (sCPID == "INVESTOR")
1649+
{
1650+
labelBeaconIcon->setPixmap(QIcon(":/icons/beacon_red").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1651+
labelBeaconIcon->setToolTip(tr("Wallet status is INVESTOR, but the wallet is not configured for investor mode. "
1652+
"If you intend to be an investor only, please remove the email entry in the config file, "
1653+
"otherwise you need to check your email entry and your BOINC installation."));
1654+
}
1655+
// CPID resolves to non-INVESTOR and beacon exists.
1656+
else if (sCPID != "INVESTOR" && beacon_status.hasBeacon)
1657+
{
1658+
double seconds_in_day = 24.0 * 60.0 * 60.0;
1659+
1660+
beacon_age = (double) (GetAdjustedTime() - beacon_status.iBeaconTimestamp) / seconds_in_day;
1661+
time_to_expiration = ((double) MaxBeaconAge() / seconds_in_day) - beacon_age;
1662+
advertise_threshold = BeaconAgeAdvertiseThreshold() / seconds_in_day;
1663+
1664+
// If beacon does not need to be renewed...
1665+
if (beacon_age < advertise_threshold)
1666+
{
1667+
labelBeaconIcon->setPixmap(QIcon(":/icons/beacon_green").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1668+
labelBeaconIcon->setToolTip(tr("CPID: %1\n"
1669+
"Beacon age: %2 day(s)\n"
1670+
"Expires: %3 day(s)\n"
1671+
"Beacon status is good.").arg(QString(sCPID.c_str()))
1672+
.arg(QString(std::to_string((int) std::round(beacon_age)).c_str()))
1673+
.arg(QString(std::to_string((int) time_to_expiration).c_str())));
1674+
}
1675+
// If between start of period where able to renew and 15 days left until expiration, time to renew!...
1676+
else if (beacon_age >= advertise_threshold && time_to_expiration > 15.0)
1677+
{
1678+
labelBeaconIcon->setPixmap(QIcon(":/icons/beacon_yellow").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1679+
labelBeaconIcon->setToolTip(tr("CPID: %1\n"
1680+
"Beacon age: %2 day(s)\n"
1681+
"Expires: %3 day(s)\n"
1682+
"Beacon should be renewed.").arg(QString(sCPID.c_str()))
1683+
.arg(QString(std::to_string((int) std::round(beacon_age)).c_str()))
1684+
.arg(QString(std::to_string((int) time_to_expiration).c_str())));
1685+
}
1686+
// If magnitude is zero (which is common for new beacons and lapsed beacons that have been renewed)...
1687+
else if (!beacon_status.dPriorSBMagnitude)
1688+
{
1689+
labelBeaconIcon->setPixmap(QIcon(":/icons/beacon_yellow").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1690+
labelBeaconIcon->setToolTip(tr("CPID: %1\n"
1691+
"Beacon age: %2 day(s)\n"
1692+
"Expires: %3 day(s)\n"
1693+
"Magnitude is zero, which may prevent staking with research rewards."
1694+
"Please check your magnitude after the next superblock.").arg(QString(sCPID.c_str()))
1695+
.arg(QString(std::to_string((int) std::round(beacon_age)).c_str()))
1696+
.arg(QString(std::to_string((int) time_to_expiration).c_str())));
1697+
}
1698+
// If only 15 days left to renew, red alert!...
1699+
else if (time_to_expiration <= 15.0)
1700+
{
1701+
labelBeaconIcon->setPixmap(QIcon(":/icons/beacon_red").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1702+
labelBeaconIcon->setToolTip(tr("CPID: %1\n"
1703+
"Beacon age: %2 day(s)\n"
1704+
"Expires: %3 day(s)\n"
1705+
"BEACON SHOULD BE RENEWED IMMEDIATELY TO PREVENT LAPSE.").arg(QString(sCPID.c_str()))
1706+
.arg(QString(std::to_string((int) std::round(beacon_age)).c_str()))
1707+
.arg(QString(std::to_string((int) time_to_expiration).c_str())));
1708+
}
1709+
}
1710+
// CPID resolves, but no active beacon present.
1711+
else if (sCPID != "INVESTOR" && !beacon_status.hasBeacon)
1712+
{
1713+
labelBeaconIcon->setPixmap(QIcon(":/icons/beacon_red").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
1714+
labelBeaconIcon->setToolTip(tr("There is a CPID, %1, but there is no active beacon. "
1715+
"Your beacon may be expired or never advertised. Please "
1716+
"advertise a new beacon.").arg(QString(sCPID.c_str())));
1717+
}
1718+
}
16331719
}
File renamed without changes.

src/rpcblockchain.cpp

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -805,42 +805,36 @@ UniValue beaconstatus(const UniValue& params, bool fHelp)
805805

806806
// Search for beacon, and report on beacon status.
807807

808-
std::string sCPID = NN::GetPrimaryCpid();
808+
std::string sCPID;
809809

810810
if (params.size() > 0)
811811
sCPID = params[0].get_str();
812812

813-
LOCK(cs_main);
814-
815-
std::string sPubKey = GetBeaconPublicKey(sCPID, false);
816-
int64_t iBeaconTimestamp = BeaconTimeStamp(sCPID);
817-
std::string timestamp = TimestampToHRDate(iBeaconTimestamp);
818-
bool hasBeacon = HasActiveBeacon(sCPID);
813+
// If sCPID is supplied, uses that. If not, then sCPID is filled in from GetPrimaryCPID.
814+
BeaconStatus beacon_status = GetBeaconStatus(sCPID);
819815

820816
res.pushKV("CPID", sCPID);
821-
res.pushKV("Beacon Exists",YesNo(hasBeacon));
822-
res.pushKV("Beacon Timestamp",timestamp.c_str());
823-
res.pushKV("Public Key", sPubKey.c_str());
824-
res.pushKV("Private Key", "not-shown"); //TODO: show the key?
817+
res.pushKV("Beacon Exists", YesNo(beacon_status.hasBeacon));
818+
res.pushKV("Beacon Timestamp", beacon_status.timestamp.c_str());
819+
res.pushKV("Public Key", beacon_status.sPubKey.c_str());
825820

826821
std::string sErr = "";
827822

828-
if (sPubKey.empty())
823+
if (beacon_status.sPubKey.empty())
829824
sErr += "Public Key Missing. ";
830825

831826
// Prior superblock Magnitude
832-
double dMagnitude = NN::Tally::GetMagnitude(NN::MiningId::Parse(sCPID));
833-
834-
res.pushKV("Magnitude (As of last superblock)", dMagnitude);
827+
res.pushKV("Magnitude (As of last superblock)", beacon_status.dPriorSBMagnitude);
835828

836-
const bool is_mine = sCPID == NN::GetPrimaryCpid();
837-
res.pushKV("Mine", is_mine);
829+
res.pushKV("Mine", beacon_status.is_mine);
838830

839-
if (is_mine && dMagnitude == 0)
831+
if (beacon_status.is_mine && beacon_status.dPriorSBMagnitude == 0)
840832
res.pushKV("Warning","Your magnitude is 0 as of the last superblock: this may keep you from staking POR blocks.");
841833

842-
if (!sPubKey.empty() && is_mine)
834+
if (!beacon_status.sPubKey.empty() && beacon_status.is_mine)
843835
{
836+
LOCK(cs_main);
837+
844838
EnsureWalletIsUnlocked();
845839

846840
bool bResult;

0 commit comments

Comments
 (0)