Skip to content

Commit

Permalink
Fix a UI freeze on 'finished' witness accounts
Browse files Browse the repository at this point in the history
There was a regression causing the UI to freeze in an infinite loop due to a zero account weight for the 'finished' account.

Fix this in two seperate ways:
1) Use a fallback weight (if zero) so that any future bugs like this can't cause an infinite loop again
2) Remove the part of the code that was causing the regression - 'finished' accounts do still have a weight for 'UI' purposes, as this weight is used to populate the historical graphs

Also clean up/clarify a few comments in the code around this.
  • Loading branch information
mjmacleod committed Apr 6, 2020
1 parent 4b37719 commit 50cf025
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/qt/_Gulden/witnessdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ WitnessInfoForAccount WitnessDialog::GetWitnessInfoForAccount(CAccount* forAccou
infoForAccount.nWitnessLength = infoForAccount.nOriginLength;
if (infoForAccount.nOriginNetworkWeight == 0)
infoForAccount.nOriginNetworkWeight = gStartingWitnessNetworkWeightEstimate;
uint64_t nEstimatedWitnessBlockPeriodOrigin = estimatedWitnessBlockPeriod(infoForAccount.nOriginWeight, infoForAccount.nOriginNetworkWeight);
uint64_t nEstimatedWitnessBlockPeriodOrigin = estimatedWitnessBlockPeriod((infoForAccount.nOriginWeight>0)?infoForAccount.nOriginWeight:gMinimumWitnessWeight, infoForAccount.nOriginNetworkWeight);
infoForAccount.pointMapForecast[0] = 0;
for (unsigned int i = nEstimatedWitnessBlockPeriodOrigin; i < infoForAccount.nWitnessLength; i += nEstimatedWitnessBlockPeriodOrigin)
{
Expand Down
7 changes: 4 additions & 3 deletions src/wallet/witness_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ CWitnessAccountStatus GetWitnessAccountStatus(CWallet* pWallet, CAccount* accoun
witnessInfo = GetWitnessInfoWrapper();
}

// Collect uspent witnesses coins on for the account
// Collect uspent witnesses coins for the account
std::vector<RouletteItem> accountItems;
for (const auto& item : witnessInfo.witnessSelectionPoolUnfiltered)
{
Expand Down Expand Up @@ -647,7 +647,7 @@ CWitnessAccountStatus GetWitnessAccountStatus(CWallet* pWallet, CAccount* accoun
throw std::runtime_error("Unable to determine witness state.");
}

// NOTE: assuming any unconfirmed tx here is a witness one to avoid getting the witness bundles and testing those, this will almost always be
// NOTE: assuming any unconfirmed tx here is a witness; avoid getting the witness bundles and testing those, this will almost always be
// correct. Any edge cases where this fails will automatically resolve once the tx confirms.
bool hasUnconfirmedWittnessTx = std::any_of(pWallet->mapWallet.begin(), pWallet->mapWallet.end(), [=](const auto& it){
const auto& wtx = it.second;
Expand All @@ -667,7 +667,8 @@ CWitnessAccountStatus GetWitnessAccountStatus(CWallet* pWallet, CAccount* accoun
account,
status,
networkWeight,
isLocked ? std::accumulate(accountItems.begin(), accountItems.end(), uint64_t(0), [](const uint64_t acc, const RouletteItem& ri){ return acc + ri.nWeight; }) : uint64_t(0),
//NB! We always want the account weight (even if expired) - otherwise how do we e.g. draw a historical graph of the expected earnings for the expired account?
std::accumulate(accountItems.begin(), accountItems.end(), uint64_t(0), [](const uint64_t acc, const RouletteItem& ri){ return acc + ri.nWeight; }),
hasScriptLegacyOutput,
hasUnconfirmedWittnessTx,
nLockFromBlock,
Expand Down
4 changes: 2 additions & 2 deletions src/wallet/witness_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ struct CWitnessAccountStatus
};

/** Get account witness status and accompanying details
* hasScriptLegacyOutput iff any of the outputs is CTxOutType::ScriptLegacyOutput
* hasUnconfirmedWittnessTx iff unconfirmed witness tx for the account (not actually checked for witness type, see implementation note)
* hasScriptLegacyOutput IFF any of the outputs is CTxOutType::ScriptLegacyOutput
* hasUnconfirmedWittnessTx IFF unconfirmed witness tx for the account (not actually checked for witness type, see implementation note)
* pWitnessInfo if != nullptr it will be filled with the witnessInfo if available
*/
CWitnessAccountStatus GetWitnessAccountStatus(CWallet* pWallet, CAccount* account, CGetWitnessInfo* pWitnessInfo = nullptr);
Expand Down

0 comments on commit 50cf025

Please sign in to comment.