Skip to content

Commit

Permalink
Corrections
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescowens committed Nov 25, 2023
1 parent a732310 commit dd7186e
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 8 deletions.
39 changes: 34 additions & 5 deletions src/gridcoin/voting/result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,18 +864,38 @@ class VoteCounter
{
CTransaction tx;

if (!m_txdb.ReadDiskTx(txid, tx)) {
LogPrint(LogFlags::VOTE, "%s: failed to read vote tx", __func__);
bool read_tx_success = false;

// This is very ugly. In testing for implement poll expiration reminders PR2716, there is an issue with ReadDiskTx
// on very fast machines, where upon receipt of a vote on an existing poll, the poll builder tests for the transaction
// BEFORE it is committed to disk. This retry loop is essentially zero overhead for an immediate success, but does
// up to 10 tries over up to 2.5 seconds total to "wait" for the transaction to appear in leveldb.
for (unsigned int i = 0; i < 10; ++i) {
if (m_txdb.ReadDiskTx(txid, tx)) {
read_tx_success = true;
break;
} else {
LogPrintf("WARN: %s: failed to read vote tx in try %u", __func__, i + 1);
}

if (!MilliSleep(250)) {
// Interrupt with throw if MilliSleep interrupted by op sys signal.
throw InvalidVoteError();
}
}

if (!read_tx_success) {
LogPrintf("WARN: %s: failed to read vote tx after 10 tries", __func__);
throw InvalidVoteError();
}

if (tx.nTime < m_poll.m_timestamp) {
LogPrint(LogFlags::VOTE, "%s: tx earlier than poll", __func__);
LogPrintf("WARN: %s: tx earlier than poll", __func__);
throw InvalidVoteError();
}

if (m_poll.Expired(tx.nTime)) {
LogPrint(LogFlags::VOTE, "%s: tx exceeds expiration", __func__);
LogPrintf("WARN: %s: tx exceeds expiration", __func__);
throw InvalidVoteError();
}

Expand All @@ -885,7 +905,7 @@ class VoteCounter
}

if (!contract.WellFormed()) {
LogPrint(LogFlags::VOTE, "%s: skipped bad contract", __func__);
LogPrintf("WARN: %s: skipped bad contract", __func__);
continue;
}

Expand Down Expand Up @@ -1259,6 +1279,15 @@ VoteDetail::VoteDetail() : m_amount(0), m_magnitude(Magnitude::Zero()), m_ismine
{
}

VoteDetail::VoteDetail(const VoteDetail &original_votedetail)
: m_amount(original_votedetail.m_amount)
, m_mining_id(original_votedetail.m_mining_id)
, m_magnitude(original_votedetail.m_magnitude)
, m_ismine(original_votedetail.m_ismine)
, m_responses(original_votedetail.m_responses)
{
}

bool VoteDetail::Empty() const
{
return m_amount == 0 && m_magnitude == 0;
Expand Down
7 changes: 7 additions & 0 deletions src/gridcoin/voting/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ class PollResult
//!
VoteDetail();

//!
//! \brief User copy constructor.
//!
//! \param original_votedetail
//!
VoteDetail(const VoteDetail& original_votedetail);

//!
//! \brief Determine whether a vote contributes no weight.
//!
Expand Down
5 changes: 5 additions & 0 deletions src/qt/voting/polltab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ PollTab::PollTab(QWidget* parent)
connect(ui->table, &QAbstractItemView::doubleClicked, this, &PollTab::showPreferredDialog);
connect(ui->table, &QWidget::customContextMenuRequested, this, &PollTab::showTableContextMenu);
connect(m_polltable_model.get(), &PollTableModel::layoutChanged, this, &PollTab::finishRefresh);

// Forward the polltable model signal to the Poll Tab signal to avoid having to directly include the PollTableModel
// in the voting page.
connect(m_polltable_model.get(), &PollTableModel::newVoteReceivedAndPollMarkedDirty,
this, &PollTab::newVoteReceivedAndPollMarkedDirty);
}

PollTab::~PollTab()
Expand Down
3 changes: 3 additions & 0 deletions src/qt/voting/polltab.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class PollTab : public QWidget
void setVotingModel(VotingModel* voting_model);
void setPollFilterFlags(GRC::PollFilterFlag flags);

signals:
void newVoteReceivedAndPollMarkedDirty();

public slots:
void changeViewMode(const ViewId view_id);
void refresh();
Expand Down
6 changes: 6 additions & 0 deletions src/qt/voting/polltablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "qt/guiutil.h"
#include "qt/voting/polltablemodel.h"
#include "qt/voting/votingmodel.h"
#include "logging.h"

#include <QtConcurrentRun>
#include <QSortFilterProxyModel>
Expand Down Expand Up @@ -255,6 +256,9 @@ const PollItem* PollTableModel::rowItem(int row) const
void PollTableModel::refresh()
{
if (!m_voting_model || !m_refresh_mutex.tryLock()) {
LogPrint(BCLog::LogFlags::VOTE, "INFO: %s: m_refresh_mutex is already taken, so tryLock failed",
__func__);

return;
}

Expand All @@ -269,6 +273,8 @@ void PollTableModel::refresh()
void PollTableModel::handlePollStaleFlag(QString poll_txid_string)
{
m_data_model->handlePollStaleFlag(poll_txid_string);

emit newVoteReceivedAndPollMarkedDirty();
}

void PollTableModel::changeTitleFilter(const QString& pattern)
Expand Down
3 changes: 3 additions & 0 deletions src/qt/voting/polltablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ class PollTableModel : public QSortFilterProxyModel
QString columnName(int offset) const;
const PollItem* rowItem(int row) const;

signals:
void newVoteReceivedAndPollMarkedDirty();

public slots:
void refresh();
void changeTitleFilter(const QString& pattern);
Expand Down
8 changes: 5 additions & 3 deletions src/qt/voting/votingpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,14 @@ void VotingPage::setVotingModel(VotingModel* model)
// Now that PollItem caching is available, automatically refresh current poll tab on receipt of new poll or vote.
connect(model, &VotingModel::newPollReceived, [this]() {
ui->pollReceivedLabel->show();
currentTab().refresh();
getActiveTab()->refresh();
ui->pollReceivedLabel->hide();
});

connect(model, &VotingModel::newVoteReceived, [this]() {
currentTab().refresh();
// Using the newVoteReceivedAndPollMarkedDirty instead of newVoteReceived insures the poll staleness flag in the appropriate
// poll item has been marked dirty before the refresh is called.
connect(getActiveTab(), &PollTab::newVoteReceivedAndPollMarkedDirty, [this]() {
getActiveTab()->refresh();
});
}

Expand Down

0 comments on commit dd7186e

Please sign in to comment.