Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
17491eb
refactor: drop `emitCoinJoinEnabledChanged()`, use `setOption()` instead
kwvg Jan 28, 2026
2deba78
refactor: improve CoinJoin tab nullptr checks, bail-out condition
kwvg Jan 21, 2026
8a0907c
move-only: move `subFeeFromAmount` into `verticalLayout_2`
kwvg Jan 18, 2026
45da71c
chore: enforce alphabetical sorting in `src/Makefile.qt.include`
kwvg Jan 20, 2026
c8558b8
refactor: add `getScaledFont` helper, keep `getFont` internal
kwvg Jan 22, 2026
1c7cfcc
refactor: add `pruneStaleEntities` helper to deduplicate pruning
kwvg Jan 20, 2026
fa48b81
move-only: split proposal model out to `src/qt/proposalmodel.{cpp,h}`
kwvg Jan 28, 2026
a709391
fix: use `unique_ptr` and more bounds checking in `qt/proposalmodel`
kwvg Jan 22, 2026
ae70706
refactor: drop `QObject` inheritance, precalculate hash string
kwvg Jan 22, 2026
8a7f4e9
qt: add styling support for QTextEdit `<b>` and `<h{1-3}>` elements
kwvg Jan 28, 2026
804a239
qt: use show/hide for "Governance" tab to avoid client restart
kwvg Jan 21, 2026
ef0a787
refactor: track "Governance" tab show/hide in `OptionsModel`
kwvg Jan 21, 2026
765213c
qt: use show/hide for "Masternodes" tab to avoid client restart
kwvg Jan 21, 2026
a4d51e2
refactor: track "Masternodes" tab show/hide in `OptionsModel`
kwvg Jan 21, 2026
8265b49
refactor: repurpose `transactiondescdialog` as a generic desc. container
kwvg Jan 22, 2026
bd2979b
qt: reorder columns in "Governance" tab, make width elastic for key cols
kwvg Jan 22, 2026
4166586
qt: change layout of "Governance" tab controls for readability
kwvg Jan 24, 2026
d24ecbb
qt: report compact voting status and expanded details in tooltip
kwvg Jan 22, 2026
db6deb7
qt: use monospace font for hashes in "Governance" tab
kwvg Jan 22, 2026
86b9f5e
qt: report proposal info using QTextEdit instead of an alert with JSON
kwvg Jan 22, 2026
f4bd648
qt: report more proposal information in description, calculate payments
kwvg Jan 22, 2026
5473a74
qt: cleanup proposal context menu, add copy JSON and visit URL options
kwvg Jan 22, 2026
2feba7f
qt: replace "Active" column with icons that reflect lifecycle status
kwvg Jan 24, 2026
9f2d8dc
qt: increment in-progress icon progression based on time within cycle
kwvg Jan 24, 2026
86063b3
fix: pre-calculate icons to avoid resize stutter
kwvg Jan 24, 2026
7b72a2f
qt: list locally recorded proposals in "Governance" tab
kwvg Jan 22, 2026
af9f09f
qt: add blank canvas if there's no proposals to display
kwvg Jan 22, 2026
6d0bc31
qt: adjust layout of details page of proposal wizard to resemble DGT
kwvg Jan 20, 2026
4a75714
qt: drop JSON/hex confirmation page, use description dialogs instead
kwvg Jan 21, 2026
4014ea0
qt: use `SendConfirmationDialog` instead of `QMessageBox` for confirm
kwvg Jan 20, 2026
a45de4c
qt: remove remaining pages from proposal wizard
kwvg Jan 20, 2026
d386673
qt: add "Resume Proposal" button for post-confirmation broadcast
kwvg Jan 22, 2026
781c4b3
qt: disable proposal buttons until synced, creation button w/o funds
kwvg Jan 21, 2026
55cc251
qt: simplify `reconcile()` routine, discard old data wholesale.
kwvg Jan 24, 2026
de9cb71
refactor: `qt/proposalwizard.{cpp,h}` -> `qt/proposalcreate.{cpp,h}`
kwvg Jan 22, 2026
697ced0
fix: avoid double-free by clearing before dtor semaphore cleanup
kwvg Jan 28, 2026
4b76d4f
fix: check for `llmq_ctx` before accessing `isman`
kwvg Jan 28, 2026
b9aa5a6
fix(qt): align headers in debug window's information tab
kwvg Jan 26, 2026
18219ea
refactor(qt): move debug window stats to separate information widget
kwvg Jan 26, 2026
ddc2d61
refactor(qt): move Dash-specific reporting to network widget
kwvg Jan 28, 2026
e53c5c3
chore(qt): update header and label descriptions based on capability
kwvg Jan 26, 2026
bb71e41
feat(qt): report pending and awaiting islocks, unprotected transactions
kwvg Jan 26, 2026
f1d1821
trivial(qt): report chainlock time to maintain parity with block fields
kwvg Jan 27, 2026
c383cbc
feat(qt): report credit pool diff, limit, locked and pending unlocks
kwvg Jan 27, 2026
2c230e4
feat(qt): report active quorums and their health
kwvg Jan 28, 2026
dd6e20b
refactor(qt): use horizontal layout with vertical grids, reorder data
kwvg Jan 27, 2026
dc6e788
feat(qt): report governance information
kwvg Jan 28, 2026
e7c786d
feat(qt): add donut chart to show proposal usage of overall budget
kwvg Jan 28, 2026
04e171d
fix: throttle chart updates to one second to prevent lag when syncing
kwvg Jan 28, 2026
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
140 changes: 81 additions & 59 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -20,62 +20,73 @@ QT_FORMS_UI = \
qt/forms/askpassphrasedialog.ui \
qt/forms/coincontroldialog.ui \
qt/forms/createwalletdialog.ui \
qt/forms/debugwindow.ui \
qt/forms/descriptiondialog.ui \
qt/forms/editaddressdialog.ui \
qt/forms/informationwidget.ui \
qt/forms/governanceinfo.ui \
qt/forms/governancelist.ui \
qt/forms/proposalwizard.ui \
qt/forms/helpmessagedialog.ui \
qt/forms/intro.ui \
qt/forms/modaloverlay.ui \
qt/forms/masternodelist.ui \
qt/forms/mnemonicverificationdialog.ui \
qt/forms/qrdialog.ui \
qt/forms/modaloverlay.ui \
qt/forms/networkwidget.ui \
qt/forms/openuridialog.ui \
qt/forms/optionsdialog.ui \
qt/forms/overviewpage.ui \
qt/forms/proposalcreate.ui \
qt/forms/proposalresume.ui \
qt/forms/psbtoperationsdialog.ui \
qt/forms/qrdialog.ui \
qt/forms/receivecoinsdialog.ui \
qt/forms/receiverequestdialog.ui \
qt/forms/debugwindow.ui \
qt/forms/sendcoinsdialog.ui \
qt/forms/sendcoinsentry.ui \
qt/forms/signverifymessagedialog.ui \
qt/forms/transactiondescdialog.ui
qt/forms/signverifymessagedialog.ui

QT_MOC_CPP = \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
qt/moc_appearancewidget.cpp \
qt/moc_askpassphrasedialog.cpp \
qt/moc_createwalletdialog.cpp \
qt/moc_bantablemodel.cpp \
qt/moc_bitcoin.cpp \
qt/moc_bitcoinaddressvalidator.cpp \
qt/moc_bitcoinamountfield.cpp \
qt/moc_bitcoingui.cpp \
qt/moc_bitcoinunits.cpp \
qt/moc_donutchart.cpp \
qt/moc_clientmodel.cpp \
qt/moc_coincontroldialog.cpp \
qt/moc_coincontroltreewidget.cpp \
qt/moc_createwalletdialog.cpp \
qt/moc_csvmodelwriter.cpp \
qt/moc_descriptiondialog.cpp \
qt/moc_editaddressdialog.cpp \
qt/moc_governanceinfo.cpp \
qt/moc_governancelist.cpp \
qt/moc_proposalwizard.cpp \
qt/moc_guiutil.cpp \
qt/moc_informationwidget.cpp \
qt/moc_initexecutor.cpp \
qt/moc_intro.cpp \
qt/moc_macdockiconhandler.cpp \
qt/moc_macnotificationhandler.cpp \
qt/moc_modaloverlay.cpp \
qt/moc_masternodelist.cpp \
qt/moc_mnemonicverificationdialog.cpp \
qt/moc_modaloverlay.cpp \
qt/moc_networkwidget.cpp \
qt/moc_notificator.cpp \
qt/moc_openuridialog.cpp \
qt/moc_optionsdialog.cpp \
qt/moc_optionsmodel.cpp \
qt/moc_overviewpage.cpp \
qt/moc_paymentserver.cpp \
qt/moc_peertablemodel.cpp \
qt/moc_peertablesortproxy.cpp \
qt/moc_paymentserver.cpp \
qt/moc_proposalmodel.cpp \
qt/moc_proposalcreate.cpp \
qt/moc_proposalresume.cpp \
qt/moc_psbtoperationsdialog.cpp \
qt/moc_qrdialog.cpp \
qt/moc_qrimagewidget.cpp \
Expand All @@ -91,7 +102,6 @@ QT_MOC_CPP = \
qt/moc_splashscreen.cpp \
qt/moc_trafficgraphwidget.cpp \
qt/moc_transactiondesc.cpp \
qt/moc_transactiondescdialog.cpp \
qt/moc_transactionfilterproxy.cpp \
qt/moc_transactionoverviewwidget.cpp \
qt/moc_transactiontablemodel.cpp \
Expand Down Expand Up @@ -129,26 +139,30 @@ BITCOIN_QT_H = \
qt/bitcoinamountfield.h \
qt/bitcoingui.h \
qt/bitcoinunits.h \
qt/donutchart.h \
qt/clientmodel.h \
qt/coincontroldialog.h \
qt/coincontroltreewidget.h \
qt/createwalletdialog.h \
qt/csvmodelwriter.h \
qt/descriptiondialog.h \
qt/editaddressdialog.h \
qt/governanceinfo.h \
qt/governancelist.h \
qt/proposalwizard.h \
qt/guiconstants.h \
qt/guiutil.h \
qt/guiutil_font.h \
qt/informationwidget.h \
qt/initexecutor.h \
qt/intro.h \
qt/macdockiconhandler.h \
qt/macnotificationhandler.h \
qt/macos_appnap.h \
qt/modaloverlay.h \
qt/masternodelist.h \
qt/mnemonicverificationdialog.h \
qt/modaloverlay.h \
qt/networkstyle.h \
qt/networkwidget.h \
qt/notificator.h \
qt/openuridialog.h \
qt/optionsdialog.h \
Expand All @@ -157,6 +171,9 @@ BITCOIN_QT_H = \
qt/paymentserver.h \
qt/peertablemodel.h \
qt/peertablesortproxy.h \
qt/proposalcreate.h \
qt/proposalmodel.h \
qt/proposalresume.h \
qt/psbtoperationsdialog.h \
qt/qrdialog.h \
qt/qrimagewidget.h \
Expand All @@ -174,7 +191,6 @@ BITCOIN_QT_H = \
qt/trafficgraphdata.h \
qt/trafficgraphwidget.h \
qt/transactiondesc.h \
qt/transactiondescdialog.h \
qt/transactionfilterproxy.h \
qt/transactionoverviewwidget.h \
qt/transactionrecord.h \
Expand All @@ -189,36 +205,36 @@ BITCOIN_QT_H = \
qt/winshutdownmonitor.h

QT_RES_ICONS = \
qt/res/icons/dash.ico \
qt/res/icons/dash_testnet.ico \
qt/res/icons/dash.png \
qt/res/icons/warning.png \
qt/res/icons/address-book.png \
qt/res/icons/transaction0.png \
qt/res/icons/transaction1.png \
qt/res/icons/transaction2.png \
qt/res/icons/transaction3.png \
qt/res/icons/transaction4.png \
qt/res/icons/transaction5.png \
qt/res/icons/transaction_abandoned.png \
qt/res/icons/transaction_locked.png \
qt/res/icons/connect1_16.png \
qt/res/icons/connect2_16.png \
qt/res/icons/connect3_16.png \
qt/res/icons/connect4_16.png \
qt/res/icons/dash.ico \
qt/res/icons/dash.png \
qt/res/icons/dash_testnet.ico \
qt/res/icons/editcopy.png \
qt/res/icons/editpaste.png \
qt/res/icons/eye.png \
qt/res/icons/eye_minus.png \
qt/res/icons/eye_plus.png \
qt/res/icons/fontbigger.png \
qt/res/icons/fontsmaller.png \
qt/res/icons/hd_enabled.png \
qt/res/icons/lock_closed.png \
qt/res/icons/lock_open.png \
qt/res/icons/proxy.png \
qt/res/icons/remove.png \
qt/res/icons/synced.png \
qt/res/icons/fontbigger.png \
qt/res/icons/fontsmaller.png
qt/res/icons/transaction0.png \
qt/res/icons/transaction1.png \
qt/res/icons/transaction2.png \
qt/res/icons/transaction3.png \
qt/res/icons/transaction4.png \
qt/res/icons/transaction5.png \
qt/res/icons/transaction_abandoned.png \
qt/res/icons/transaction_locked.png \
qt/res/icons/warning.png

BITCOIN_QT_BASE_CPP = \
qt/appearancewidget.cpp \
Expand All @@ -228,14 +244,18 @@ BITCOIN_QT_BASE_CPP = \
qt/bitcoinamountfield.cpp \
qt/bitcoingui.cpp \
qt/bitcoinunits.cpp \
qt/donutchart.cpp \
qt/clientmodel.cpp \
qt/csvmodelwriter.cpp \
qt/governanceinfo.cpp \
qt/guiutil.cpp \
qt/guiutil_font.cpp \
qt/informationwidget.cpp \
qt/initexecutor.cpp \
qt/intro.cpp \
qt/modaloverlay.cpp \
qt/networkstyle.cpp \
qt/networkwidget.cpp \
qt/notificator.cpp \
qt/optionsdialog.cpp \
qt/optionsmodel.cpp \
Expand All @@ -258,14 +278,17 @@ BITCOIN_QT_WALLET_CPP = \
qt/coincontroldialog.cpp \
qt/coincontroltreewidget.cpp \
qt/createwalletdialog.cpp \
qt/descriptiondialog.cpp \
qt/editaddressdialog.cpp \
qt/governancelist.cpp \
qt/proposalwizard.cpp \
qt/masternodelist.cpp \
qt/mnemonicverificationdialog.cpp \
qt/openuridialog.cpp \
qt/overviewpage.cpp \
qt/paymentserver.cpp \
qt/proposalcreate.cpp \
qt/proposalmodel.cpp \
qt/proposalresume.cpp \
qt/psbtoperationsdialog.cpp \
qt/qrdialog.cpp \
qt/qrimagewidget.cpp \
Expand All @@ -276,7 +299,6 @@ BITCOIN_QT_WALLET_CPP = \
qt/sendcoinsentry.cpp \
qt/signverifymessagedialog.cpp \
qt/transactiondesc.cpp \
qt/transactiondescdialog.cpp \
qt/transactionfilterproxy.cpp \
qt/transactionoverviewwidget.cpp \
qt/transactionrecord.cpp \
Expand All @@ -301,50 +323,50 @@ QT_RES_IMAGES = \
qt/res/images/arrow_down_light.png \
qt/res/images/arrow_left_dark.png \
qt/res/images/arrow_left_light.png \
qt/res/images/arrow_right_dark.png \
qt/res/images/arrow_right_light.png \
qt/res/images/arrow_up_dark.png \
qt/res/images/arrow_up_light.png \
qt/res/images/arrow_light_down_normal.png \
qt/res/images/arrow_light_down_hover.png \
qt/res/images/arrow_light_left_normal.png \
qt/res/images/arrow_light_down_normal.png \
qt/res/images/arrow_light_left_hover.png \
qt/res/images/arrow_light_right_normal.png \
qt/res/images/arrow_light_left_normal.png \
qt/res/images/arrow_light_right_hover.png \
qt/res/images/arrow_light_up_normal.png \
qt/res/images/arrow_light_right_normal.png \
qt/res/images/arrow_light_up_hover.png \
qt/res/images/checkbox_normal_dark.png \
qt/res/images/checkbox_normal_hover_dark.png \
qt/res/images/checkbox_normal_disabled_dark.png \
qt/res/images/arrow_light_up_normal.png \
qt/res/images/arrow_right_dark.png \
qt/res/images/arrow_right_light.png \
qt/res/images/arrow_up_dark.png \
qt/res/images/arrow_up_light.png \
qt/res/images/checkbox_checked_dark.png \
qt/res/images/checkbox_checked_hover_dark.png \
qt/res/images/checkbox_checked_disabled_dark.png \
qt/res/images/checkbox_checked_disabled_light.png \
qt/res/images/checkbox_checked_hover_dark.png \
qt/res/images/checkbox_checked_hover_light.png \
qt/res/images/checkbox_checked_light.png \
qt/res/images/checkbox_normal_dark.png \
qt/res/images/checkbox_normal_disabled_dark.png \
qt/res/images/checkbox_normal_disabled_light.png \
qt/res/images/checkbox_normal_hover_dark.png \
qt/res/images/checkbox_normal_hover_light.png \
qt/res/images/checkbox_normal_light.png \
qt/res/images/checkbox_partly_checked_dark.png \
qt/res/images/checkbox_partly_checked_hover_dark.png \
qt/res/images/checkbox_partly_checked_disabled_dark.png \
qt/res/images/checkbox_normal_light.png \
qt/res/images/checkbox_normal_hover_light.png \
qt/res/images/checkbox_normal_disabled_light.png \
qt/res/images/checkbox_checked_light.png \
qt/res/images/checkbox_checked_hover_light.png \
qt/res/images/checkbox_checked_disabled_light.png \
qt/res/images/checkbox_partly_checked_light.png \
qt/res/images/checkbox_partly_checked_hover_light.png \
qt/res/images/checkbox_partly_checked_disabled_light.png \
qt/res/images/checkbox_partly_checked_hover_dark.png \
qt/res/images/checkbox_partly_checked_hover_light.png \
qt/res/images/checkbox_partly_checked_light.png \
qt/res/images/dash_logo_toolbar.png \
qt/res/images/dash_logo_toolbar_blue.png \
qt/res/images/radio_normal_dark.png \
qt/res/images/radio_normal_hover_dark.png \
qt/res/images/radio_checked_dark.png \
qt/res/images/radio_checked_hover_dark.png \
qt/res/images/radio_normal_disabled_dark.png \
qt/res/images/radio_checked_disabled_dark.png \
qt/res/images/radio_normal_light.png \
qt/res/images/radio_normal_hover_light.png \
qt/res/images/radio_checked_light.png \
qt/res/images/radio_checked_disabled_light.png \
qt/res/images/radio_checked_hover_dark.png \
qt/res/images/radio_checked_hover_light.png \
qt/res/images/radio_checked_light.png \
qt/res/images/radio_normal_dark.png \
qt/res/images/radio_normal_disabled_dark.png \
qt/res/images/radio_normal_disabled_light.png \
qt/res/images/radio_checked_disabled_light.png \
qt/res/images/radio_normal_hover_dark.png \
qt/res/images/radio_normal_hover_light.png \
qt/res/images/radio_normal_light.png \
qt/res/images/splash.png

QT_RES_CSS = \
Expand Down
2 changes: 1 addition & 1 deletion src/chainlock/chainlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ void CChainLocksHandler::EnforceBestChainLock()
}

GetMainSignals().NotifyChainLock(currentBestChainLockBlockIndex, clsig, clsig->ToString());
uiInterface.NotifyChainLock(clsig->getBlockHash().ToString(), clsig->getHeight());
uiInterface.NotifyChainLock(clsig->getBlockHash().ToString(), clsig->getHeight(), currentBestChainLockBlockIndex->GetBlockTime());
::g_stats_client->gauge("chainlocks.blockHeight", clsig->getHeight(), 1.0f);
}

Expand Down
14 changes: 14 additions & 0 deletions src/governance/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,20 @@ int CGovernanceObject::GetAbstainCount(const CDeterministicMNList& tip_mn_list,
return CountMatchingVotes(tip_mn_list, eVoteSignalIn, VOTE_OUTCOME_ABSTAIN);
}

std::pair<uint16_t, uint16_t> CGovernanceObject::GetUniqueVoterCount(const CDeterministicMNList& tip_mn_list, vote_signal_enum_t eVoteSignalIn) const
{
LOCK(cs);
uint16_t regular{0}, evo{0};
for (const auto& [outpoint, rec_vote] : mapCurrentMNVotes) {
if (auto it = rec_vote.mapInstances.find(eVoteSignalIn); it != rec_vote.mapInstances.end()) {
if (auto dmn = tip_mn_list.GetMNByCollateral(outpoint)) {
dmn->nType == MnType::Evo ? evo++ : regular++;
}
}
}
return {regular, evo};
}

bool CGovernanceObject::GetCurrentMNVotes(const COutPoint& mnCollateralOutpoint, vote_rec_t& voteRecord) const
{
LOCK(cs);
Expand Down
2 changes: 2 additions & 0 deletions src/governance/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ class CGovernanceObject
EXCLUSIVE_LOCKS_REQUIRED(!cs);
int GetAbstainCount(const CDeterministicMNList& tip_mn_list, vote_signal_enum_t eVoteSignalIn) const
EXCLUSIVE_LOCKS_REQUIRED(!cs);
std::pair<uint16_t, uint16_t> GetUniqueVoterCount(const CDeterministicMNList& tip_mn_list, vote_signal_enum_t eVoteSignalIn) const
EXCLUSIVE_LOCKS_REQUIRED(!cs);

bool GetCurrentMNVotes(const COutPoint& mnCollateralOutpoint, vote_rec_t& voteRecord) const
EXCLUSIVE_LOCKS_REQUIRED(!cs);
Expand Down
4 changes: 2 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2391,9 +2391,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
}
const std::string chainlock_notify = args.GetArg("-chainlocknotify", "");
if (!chainlock_notify.empty()) {
uiInterface.NotifyChainLock_connect([chainlock_notify](const std::string& bestChainLockHash, int bestChainLockHeight) {
uiInterface.NotifyChainLock_connect([chainlock_notify](const std::string& best_hash, int /* best_height */, int64_t /* best_block_time */) {
std::string command = chainlock_notify;
ReplaceAll(command, "%s", bestChainLockHash);
ReplaceAll(command, "%s", best_hash);
std::thread t(runCommand, command);
t.detach(); // thread runs free
});
Expand Down
18 changes: 18 additions & 0 deletions src/instantsend/instantsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,24 @@ size_t CInstantSendManager::GetInstantSendLockCount() const
return db.GetInstantSendLockCount();
}

size_t CInstantSendManager::GetPendingInstantSendLockCount() const
{
LOCK(cs_pendingLocks);
return pendingInstantSendLocks.size();
}

size_t CInstantSendManager::GetPendingNoTxInstantSendLockCount() const
{
LOCK(cs_pendingLocks);
return pendingNoTxInstantSendLocks.size();
}

size_t CInstantSendManager::GetNonLockedTxCount() const
{
LOCK(cs_nonLocked);
return nonLockedTxs.size();
}

void CInstantSendManager::CacheBlockHeightInternal(const CBlockIndex* const block_index) const
{
AssertLockHeld(cs_height_cache);
Expand Down
Loading
Loading