Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ bool fUseFastIndex = false;

std::map<std::string, int> mvTimers; // Contains event timers that reset after max ms duration iterator is exceeded

// Temporary block version 11 transition helpers:
int64_t g_v11_timestamp = 0;
int64_t g_v11_legacy_beacon_days = 14;

// End of Gridcoin Global vars

//////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -3752,6 +3756,12 @@ bool GridcoinServices()
// legacy transactions that cannot validate:
//
mempool.DiscardVersion1();

// Set the timestamp for the block version 11 threshold. This
// is temporary. Remove this variable in a release that comes
// after the hard fork.
//
g_v11_timestamp = pindexBest->nTime;
}

//Dont perform the following functions if out of sync
Expand Down Expand Up @@ -4087,6 +4097,15 @@ bool LoadBlockIndex(bool fAllowNew)
nNewIndex2 = 36500;
//1-24-2016
MAX_OUTBOUND_CONNECTIONS = (int)GetArg("-maxoutboundconnections", 8);

// Temporary transition to version 2 beacons after the block version 11
// hard-fork:
//
try {
g_v11_legacy_beacon_days = std::stoi(GetArg("-v11beacondays", ""));
} catch (...) {
g_v11_legacy_beacon_days = 365 * 100; // Big number that won't wrap.
}
}

LogPrintf("Mode=%s", fTestNet ? "TestNet" : "Prod");
Expand Down
35 changes: 33 additions & 2 deletions src/neuralnet/beacon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
using namespace NN;
using LogFlags = BCLog::LogFlags;

extern int64_t g_v11_timestamp;
extern int64_t g_v11_legacy_beacon_days;

namespace {
BeaconRegistry g_beacons;

Expand Down Expand Up @@ -130,7 +133,18 @@ int64_t Beacon::Age(const int64_t now) const

bool Beacon::Expired(const int64_t now) const
{
return Age(now) > MAX_AGE;
if (Age(now) > MAX_AGE) {
return true;
}

// Temporary transition to version 2 beacons after the block version 11
// hard-fork:
//
if (m_timestamp <= g_v11_timestamp) {
return now - g_v11_timestamp > g_v11_legacy_beacon_days * 86400;
}

return false;
}

bool Beacon::Renewable(const int64_t now) const
Expand Down Expand Up @@ -374,6 +388,11 @@ bool BeaconRegistry::Validate(const Contract& contract) const

const auto payload = contract.SharePayloadAs<BeaconPayload>();

if (payload->m_version < 2) {
LogPrint(LogFlags::CONTRACT, "%s: Legacy beacon contract", __func__);
return false;
}

if (!payload->WellFormed(contract.m_action.Value())) {
LogPrint(LogFlags::CONTRACT, "%s: Malformed beacon contract", __func__);
return false;
Expand All @@ -393,14 +412,26 @@ bool BeaconRegistry::Validate(const Contract& contract) const
// Self-service beacon removal allowed when the signature matches the key
// of the original beacon:
if (contract.m_action == ContractAction::REMOVE) {
return current_beacon->m_public_key == payload->m_beacon.m_public_key;
if (current_beacon->m_public_key != payload->m_beacon.m_public_key) {
LogPrint(LogFlags::CONTRACT, "%s: Beacon key mismatch", __func__);
return false;
}

return true;
}

// Self-service beacon replacement will be authenticated by the scrapers:
if (current_beacon->m_public_key != payload->m_beacon.m_public_key) {
return true;
}

// Transition to version 2 beacons after the block version 11 threshold.
// Legacy beacons are not renewable:
if (current_beacon->m_timestamp <= g_v11_timestamp) {
LogPrint(LogFlags::CONTRACT, "%s: Can't renew legacy beacon", __func__);
return false;
}

if (!current_beacon->Renewable(contract.m_tx_timestamp)) {
LogPrint(LogFlags::CONTRACT,
"%s: Beacon for CPID %s is not renewable. Age: %" PRId64,
Expand Down
23 changes: 15 additions & 8 deletions src/neuralnet/researcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ std::string ExtractXML(const std::string& XMLdata, const std::string& key, const

extern CCriticalSection cs_main;
extern std::string msMiningErrors;
extern int64_t g_v11_timestamp;

namespace {
//!
Expand Down Expand Up @@ -1225,7 +1226,7 @@ bool Researcher::UpdateEmail(std::string email)
return true;
}

AdvertiseBeaconResult Researcher::AdvertiseBeacon()
AdvertiseBeaconResult Researcher::AdvertiseBeacon(const bool force)
{
const CpidOption cpid = m_mining_id.TryCpid();

Expand All @@ -1240,15 +1241,21 @@ AdvertiseBeaconResult Researcher::AdvertiseBeacon()

AdvertiseBeaconResult result(BeaconError::NONE);

if (!current_beacon) {
if (g_recent_beacons.Try(*cpid)) {
LogPrintf("%s: Beacon awaiting confirmation already", __func__);
return BeaconError::PENDING;
}

if (force) {
result = SendNewBeacon(*cpid);
} else if (g_recent_beacons.Try(*cpid)) {
LogPrintf("%s: Beacon awaiting confirmation already", __func__);
return BeaconError::PENDING;
} else if (!current_beacon) {
result = SendNewBeacon(*cpid);
} else {
result = RenewBeacon(*cpid, *current_beacon);
// Temporary transition to version 2 beacons after the block version 11
// threshold. Legacy beacons are not renewable:
if (current_beacon->m_timestamp <= g_v11_timestamp) {
result = SendNewBeacon(*cpid);
} else {
result = RenewBeacon(*cpid, *current_beacon);
}
}

if (result.Error() == BeaconError::NONE) {
Expand Down
9 changes: 8 additions & 1 deletion src/neuralnet/researcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -512,10 +512,17 @@ class Researcher
//! - The wallet is fully unlocked
//! - The wallet contains a balance sufficient to send a transaction
//!
//! The \p force parameter instructs the wallet to generate a new beacon
//! private key even when a valid beacon exists for the current CPID. It
//! allows a user to send a beacon to recover the claim to their CPID if
//! they lost the original private key.
//!
//! \param force Ignore active and pending beacons for the current CPID.
//!
//! \return A variant that contains the new public key if successful or a
//! description of the error that occurred.
//!
AdvertiseBeaconResult AdvertiseBeacon();
AdvertiseBeaconResult AdvertiseBeacon(const bool force = false);

//!
//! \brief Submit a contract to the network to revoke an existing beacon.
Expand Down
9 changes: 9 additions & 0 deletions src/neuralnet/tally.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
using namespace NN;
using LogFlags = BCLog::LogFlags;

extern int64_t g_v11_timestamp;

namespace {
//!
//! \brief Set the correct CPID from the block claim when the block index
Expand Down Expand Up @@ -173,6 +175,13 @@ class ResearcherTally

for (; pindex; pindex = pindex->pnext) {
if (pindex->nHeight + 1 == GetV11Threshold()) {
// Set the timestamp for the block version 11 threshold. This
// is temporary. Remove this variable in a release that comes
// after the hard fork. For now, this is the least cumbersome
// place to set the value:
//
g_v11_timestamp = pindex->nTime;

// This will finish loading the research accounting context
// for snapshot accrual (block version 11+):
return ActivateSnapshotAccrual(pindex, current_superblock);
Expand Down
17 changes: 17 additions & 0 deletions src/qt/forms/researcherwizardbeaconpage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,23 @@
</item>
</layout>
</item>
<item alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QLabel" name="v2BeaconNoticeLabel">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">font-weight: bold;</string>
</property>
<property name="text">
<string>All active beacon holders must send a new beacon for the protocol update.</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="continuePromptWrapper" native="true">
<layout class="QHBoxLayout" name="continuePromptLayout">
Expand Down
12 changes: 11 additions & 1 deletion src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ void OverviewPage::setResearcherModel(ResearcherModel *researcherModel)

updateResearcherStatus();
connect(researcherModel, SIGNAL(researcherChanged()), this, SLOT(updateResearcherStatus()));
connect(researcherModel, SIGNAL(magnitudeChanged()), this, SLOT(updateMagnitude()));
connect(researcherModel, SIGNAL(accrualChanged()), this, SLOT(updatePendingAccrual()));
connect(researcherModel, SIGNAL(beaconChanged()), this, SLOT(updateResearcherAlert()));
connect(ui->beaconButton, SIGNAL(clicked()), this, SLOT(onBeaconButtonClicked()));
Expand Down Expand Up @@ -279,12 +280,21 @@ void OverviewPage::updateResearcherStatus()

ui->statusLabel->setText(researcherModel->formatStatus());
ui->cpidLabel->setText(researcherModel->formatCpid());
ui->magnitudeLabel->setText(researcherModel->formatMagnitude());

updateMagnitude();
updatePendingAccrual();
updateResearcherAlert();
}

void OverviewPage::updateMagnitude()
{
if (!researcherModel) {
return;
}

ui->magnitudeLabel->setText(researcherModel->formatMagnitude());
}

void OverviewPage::updatePendingAccrual()
{
if (!researcherModel) {
Expand Down
1 change: 1 addition & 0 deletions src/qt/overviewpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public slots:
private slots:
void updateDisplayUnit();
void updateResearcherStatus();
void updateMagnitude();
void updatePendingAccrual();
void updateResearcherAlert();
void onBeaconButtonClicked();
Expand Down
27 changes: 22 additions & 5 deletions src/qt/researcher/researchermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
using namespace NN;
using LogFlags = BCLog::LogFlags;

extern int64_t g_v11_timestamp;

namespace {
constexpr double SECONDS_IN_DAY = 24.0 * 60.0 * 60.0;
constexpr int64_t BEACON_RENEWAL_WARNING_AGE = Beacon::MAX_AGE - (15 * SECONDS_IN_DAY);
Expand Down Expand Up @@ -187,7 +189,7 @@ void ResearcherModel::showWizard(WalletModel* wallet_model)
return;
}

if (hasRenewableBeacon()) {
if (hasRenewableBeacon() || needsV2BeaconUpgrade()) {
wizard->setStartId(ResearcherWizard::PageBeacon);
} else if (!actionNeeded()) {
wizard->setStartId(ResearcherWizard::PageSummary);
Expand All @@ -208,7 +210,8 @@ bool ResearcherModel::actionNeeded() const
}

return !hasEligibleProjects()
|| (!hasActiveBeacon() && !hasPendingBeacon());
|| (!hasActiveBeacon() && !hasPendingBeacon())
|| needsV2BeaconUpgrade();
}

bool ResearcherModel::hasEligibleProjects() const
Expand Down Expand Up @@ -238,9 +241,22 @@ bool ResearcherModel::hasMagnitude() const

bool ResearcherModel::needsBeaconAuth() const
{
return !hasRenewableBeacon()
&& hasPendingBeacon()
&& IsV11Enabled(nBestHeight + 1);
if (!hasPendingBeacon() || !IsV11Enabled(nBestHeight + 1)) {
return false;
}

if (!hasActiveBeacon()) {
return true;
}

return m_beacon->m_public_key != m_pending_beacon->m_public_key;
}

bool ResearcherModel::needsV2BeaconUpgrade() const
{
return m_beacon
&& m_beacon->m_timestamp <= g_v11_timestamp
&& (!m_pending_beacon || m_pending_beacon->m_timestamp <= g_v11_timestamp);
}

QString ResearcherModel::email() const
Expand Down Expand Up @@ -437,6 +453,7 @@ void ResearcherModel::refresh()
{
updateBeacon();

emit magnitudeChanged();
emit accrualChanged();
}

Expand Down
2 changes: 2 additions & 0 deletions src/qt/researcher/researchermodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class ResearcherModel : public QObject
bool hasRenewableBeacon() const;
bool hasMagnitude() const;
bool needsBeaconAuth() const;
bool needsV2BeaconUpgrade() const;

QString email() const;
QString formatCpid() const;
Expand Down Expand Up @@ -117,6 +118,7 @@ class ResearcherModel : public QObject
signals:
void researcherChanged();
void beaconChanged();
void magnitudeChanged();
void accrualChanged();

public slots:
Expand Down
1 change: 1 addition & 0 deletions src/qt/researcher/researcherwizardbeaconpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ void ResearcherWizardBeaconPage::refresh()

ui->cpidLabel->setText(m_researcher_model->formatCpid());
ui->sendBeaconButton->setVisible(isEnabled());
ui->v2BeaconNoticeLabel->setVisible(m_researcher_model->needsV2BeaconUpgrade());
ui->continuePromptWrapper->setVisible(!isEnabled());

emit completeChanged();
Expand Down
18 changes: 15 additions & 3 deletions src/rpcblockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,17 +605,29 @@ UniValue rainbymagnitude(const UniValue& params, bool fHelp)

UniValue advertisebeacon(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
if (fHelp || params.size() > 1)
throw runtime_error(
"advertisebeacon\n"
"advertisebeacon ( force )\n"
"\n"
"[force] --> If true, generate new beacon keys and send a new "
"beacon even when an active or pending beacon exists for your "
"CPID. This is useful if you lose a wallet with your original "
"beacon keys but not necessary otherwise.\n"
"\n"
"Advertise a beacon (Requires wallet to be fully unlocked)\n");

EnsureWalletIsUnlocked();

const bool force = params.size() >= 1 ? params[0].get_bool() : false;

LOCK2(cs_main, pwalletMain->cs_wallet);

NN::AdvertiseBeaconResult result = NN::Researcher::Get()->AdvertiseBeacon();
if (force && !IsV11Enabled(nBestHeight + 1)) {
throw JSONRPCError(RPC_INVALID_REQUEST,
"force not available until block " + std::to_string(GetV11Threshold()));
}

NN::AdvertiseBeaconResult result = NN::Researcher::Get()->AdvertiseBeacon(force);

if (auto public_key_option = result.TryPublicKey()) {
const NN::Beacon beacon(std::move(*public_key_option));
Expand Down
1 change: 1 addition & 0 deletions src/rpcclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "walletpassphrase" , 2 },

// Mining
{ "advertisebeacon" , 0 },
{ "superblocks" , 0 },
{ "superblocks" , 1 },

Expand Down
Loading