Skip to content

Commit 5bef3dc

Browse files
Merge dashpay#7110: feat(qt): UI refresh (2/n, update "Governance" Tab layout, lifecycle icons, description dialogs, resumable proposal creation)
707ce77 refactor: `qt/proposalwizard.{cpp,h}` -> `qt/proposalcreate.{cpp,h}` (Kittywhiskers Van Gogh) ce94c3e fix: improve responsiveness in update after user interaction (Kittywhiskers Van Gogh) 3d53afa fix: hold `cs_main` to for consistent state when fetching GovernanceInfo (Kittywhiskers Van Gogh) a5ae10c fix: correct tooltip display unit bug, IBD status flickering (Kittywhiskers Van Gogh) 6cb7a40 qt: add pending status to signal unbroadcast proposals (Kittywhiskers Van Gogh) d1e67ff fix: disable governance UI when node runs with `--disablegovernance` (Kittywhiskers Van Gogh) 9fb0c35 qt: make governance clock opt-in (Kittywhiskers Van Gogh) a0da7de qt: disable proposal buttons until synced, creation button w/o funds (Kittywhiskers Van Gogh) 080c8fb qt: add "Resume Proposal" for post-confirmation broadcast (Kittywhiskers Van Gogh) 2883527 qt: remove remaining pages from proposal wizard (Kittywhiskers Van Gogh) 90e0375 qt: use `SendConfirmationDialog` instead of `QMessageBox` for confirm (Kittywhiskers Van Gogh) 3ca061f qt: drop JSON/hex confirmation page, use description dialogs instead (Kittywhiskers Van Gogh) 16314e7 qt: adjust layout of details page of proposal wizard to resemble DGT (Kittywhiskers Van Gogh) 2d8cffe qt: add blank canvas if there's no proposals to display (Kittywhiskers Van Gogh) 1a1d56e qt: list locally recorded proposals in "Governance" tab (Kittywhiskers Van Gogh) 28b67d3 qt: replace "Active" column with icons that reflect voting status (Kittywhiskers Van Gogh) 5f95737 qt: add voting ballot icon (Kittywhiskers Van Gogh) af65c0e qt: cleanup proposal context menu, add copy JSON and visit URL options (Kittywhiskers Van Gogh) 552f591 qt: report more proposal information in description, calculate payments (Kittywhiskers Van Gogh) 4295471 qt: report proposal info using QTextEdit instead of an alert with JSON (Kittywhiskers Van Gogh) f45fe85 qt: use monospace font for hashes in "Governance" tab (Kittywhiskers Van Gogh) c0d8454 qt: report compact voting status and expanded details in tooltip (Kittywhiskers Van Gogh) b2b9aa1 qt: change layout of "Governance" tab controls for readability (Kittywhiskers Van Gogh) 9bb7b0a qt: reorder columns in "Governance" tab, make width elastic for key cols (Kittywhiskers Van Gogh) 8257eac qt: decouple chain sync indicator from governance sync (Kittywhiskers Van Gogh) 662703e qt: add governance cycle status bar icon (Kittywhiskers Van Gogh) a7328e9 qt: add moon phase icons for governance cycle indicator (Kittywhiskers Van Gogh) c85e5cb qt: move proposal list fetch to thread and use debounce timer (Kittywhiskers Van Gogh) 5af2bb9 qt: expose `NotifyGovernanceChanged` signal to UI code (Kittywhiskers Van Gogh) a773635 qt: move masternode list fetch logic to thread and use debounce timer (Kittywhiskers Van Gogh) Pull request description: ## Additional Information * Depends on dashpay#7112 * Depends on dashpay#7134 | v23.0.2 (cdc5a63) | This PR (WIP code) | | -------------------- | ------------------- | | ![](https://github.com/user-attachments/assets/16335e93-7e76-4fc2-a4b0-99b251b06457) | ![](https://github.com/user-attachments/assets/754892fe-4d03-4c1c-b871-71558f06bcf7) | | ![](https://github.com/user-attachments/assets/02aab041-3a0a-409a-9eac-49bf0978e890) | ![](https://github.com/user-attachments/assets/8ccc3a20-1ea9-44f4-8780-36b77f9fd88f) | | ![](https://github.com/user-attachments/assets/41ff6ed2-4072-4607-bf37-4643d93ae0e2) | ![](https://github.com/user-attachments/assets/fc4ac6e9-543b-4f6d-ab60-014a6280f6fb) | | <div align="center">Client doesn't have UI element</div> | ![](https://github.com/user-attachments/assets/f1ca0ab4-2a6c-4df9-95c4-a0667ec4dcb8) | | <div align="center">Client doesn't produce a warning</div> | ![](https://github.com/user-attachments/assets/5098acd5-1928-485a-94a0-c9747a276ceb) | | <div align="center">Client cannot show wallet-stored history</div> | ![](https://github.com/user-attachments/assets/f27e5e2e-616c-41bd-b370-171144e0787c) | #### Proposal Creation | v23.0.2 (cdc5a63) | This PR (WIP code) | | -------------------- | ------------------- | | ![](https://github.com/user-attachments/assets/bb29cbd9-de00-4c90-83eb-8cd3681a27ef) | ![](https://github.com/user-attachments/assets/724748e1-e55e-4259-b48d-45465762e7bb) | | ![](https://github.com/user-attachments/assets/4cf73f49-f08b-428f-9cb0-a9cad30b9c42) | ![](https://github.com/user-attachments/assets/c4019760-d875-4704-9302-b7b1e2c7e9de) | | <div align="center">See above</div> | ![](https://github.com/user-attachments/assets/37e829f4-4367-426e-95ba-aaa6c6b64af8) | | ![](https://github.com/user-attachments/assets/54396ad0-4fb6-4757-92e0-f748208592ea) | ![](https://github.com/user-attachments/assets/a02e9e37-feb3-4790-872f-7ac14c49e3f7) | | <div align="center">See below</div> | ![](https://github.com/user-attachments/assets/8e788bdb-80cb-493f-a215-e4e13abae9e8) | | ![](https://github.com/user-attachments/assets/d1a3813e-f22b-4617-be89-babe0e06e28d) | ![](https://github.com/user-attachments/assets/abf4d09d-eb94-4665-9d27-8ec4b4928bef) | | ![](https://github.com/user-attachments/assets/64320939-9a37-4b6e-917a-4af40011238e) | <div align="center">No equivalent page. Broadcasting is made available after relay threshold met.</div> | | ![](https://github.com/user-attachments/assets/d4d47000-a342-4246-9ada-a62735d52445) | ![](https://github.com/user-attachments/assets/0f2b91c1-2fb8-4a61-8e77-619883bde1a0) | | ![](https://github.com/user-attachments/assets/b50407e1-cd48-4b33-833d-65652cb52d61) | <div align="center">No equivalent page</div> | | ![](https://github.com/user-attachments/assets/d2ac168d-5dde-456e-852a-37aee241adec) | ![](https://github.com/user-attachments/assets/dfbc6dfe-73e4-447c-83b1-5dc5fa639c88) | | <div align="center">No equivalent page</div> | ![](https://github.com/user-attachments/assets/0b1b9e25-d86b-40dd-a60c-c62997d5c0ff) | ## Breaking Changes None expected. ## Checklist - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)** - [x] I have made corresponding changes to the documentation **(note: N/A)** - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: Seems to be working correctly. Light ACK 707ce77 Tree-SHA512: 66db006c1aca6f9c5081ba6daff9b55ab82528342d3bf1083639f6f3a969773c9c8936cfbc61d190a658e1da6c937fb41ea99b7d7a2a4533e401758045d47b8e
2 parents 1a461a0 + 707ce77 commit 5bef3dc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2916
-1627
lines changed

contrib/devtools/gen_moon_icons.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2026 The Dash Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
import math
7+
import os
8+
import struct
9+
import zlib
10+
11+
OUTPUT_PX = 64
12+
CENTER = OUTPUT_PX / 2
13+
RADIUS = 26
14+
STROKE_WIDTH = 2.0
15+
INNER_GAP_INSET = 3.0
16+
17+
18+
def make_png(pixels):
19+
"""Encode RGBA pixel data as a PNG file."""
20+
raw = bytearray()
21+
for y in range(OUTPUT_PX):
22+
raw.append(0) # filter byte: None
23+
for x in range(OUTPUT_PX):
24+
raw.extend(pixels[y][x])
25+
26+
def chunk(chunk_type, data):
27+
c = chunk_type + data
28+
return struct.pack('>I', len(data)) + c + struct.pack('>I', zlib.crc32(c) & 0xFFFFFFFF)
29+
30+
ihdr = struct.pack('>IIBBBBB', OUTPUT_PX, OUTPUT_PX, 8, 6, 0, 0, 0) # 8-bit RGBA
31+
idat = zlib.compress(bytes(raw), 9)
32+
33+
out = b'\x89PNG\r\n\x1a\n'
34+
out += chunk(b'IHDR', ihdr)
35+
out += chunk(b'IDAT', idat)
36+
out += chunk(b'IEND', b'')
37+
return out
38+
39+
40+
def moon_frame(frame):
41+
"""
42+
frame 0 = new moon (filled disc + thin inner outline gap)
43+
frame 1 = waxing crescent (small sliver on right)
44+
frame 2 = first quarter (right half illuminated)
45+
frame 3 = waxing gibbous (mostly illuminated)
46+
frame 4 = full moon (outline only)
47+
frame 5 = waning gibbous (mostly illuminated, from left)
48+
frame 6 = last quarter (left half illuminated)
49+
frame 7 = waning crescent (small sliver on left)
50+
"""
51+
if frame > 4:
52+
# Waning: horizontal mirror of the corresponding waxing frame
53+
pixels = moon_frame(8 - frame)
54+
for y in range(OUTPUT_PX):
55+
pixels[y] = pixels[y][::-1]
56+
return pixels
57+
58+
# Precompute frame-specific parameters
59+
if frame == 0:
60+
gap_outer = RADIUS - INNER_GAP_INSET
61+
gap_inner = gap_outer - STROKE_WIDTH
62+
else:
63+
frame_angle = frame * math.pi / 4
64+
65+
pixels = [[(0, 0, 0, 0)] * OUTPUT_PX for _ in range(OUTPUT_PX)]
66+
for y in range(OUTPUT_PX):
67+
for x in range(OUTPUT_PX):
68+
dx = x - CENTER + 0.5
69+
dy = y - CENTER + 0.5
70+
dist = math.sqrt(dx * dx + dy * dy)
71+
if dist > RADIUS + 1:
72+
continue
73+
disc_alpha = min(1.0, RADIUS + 1 - dist)
74+
if frame == 0:
75+
# New moon: filled disc with a thin inner outline gap
76+
if dist < gap_inner - 0.5:
77+
fill = 1.0
78+
elif dist < gap_inner + 0.5:
79+
fill = gap_inner + 0.5 - dist
80+
elif dist < gap_outer - 0.5:
81+
fill = 0.0
82+
elif dist < gap_outer + 0.5:
83+
fill = dist - (gap_outer - 0.5)
84+
else:
85+
fill = 1.0
86+
else:
87+
# Frames 1-4: terminator (shadow boundary) + outline
88+
if abs(dy) >= RADIUS:
89+
terminator_x = 0
90+
else:
91+
half_chord = math.sqrt(RADIUS * RADIUS - dy * dy)
92+
terminator_x = math.cos(frame_angle) * half_chord
93+
edge_dist = terminator_x - dx
94+
if edge_dist > 1:
95+
dark_alpha = 1.0
96+
elif edge_dist < -1:
97+
dark_alpha = 0.0
98+
else:
99+
dark_alpha = (edge_dist + 1) / 2
100+
outline_alpha = 0.0
101+
inner_edge = RADIUS - STROKE_WIDTH
102+
if dist > inner_edge:
103+
outline_alpha = min(1.0, (dist - inner_edge) / STROKE_WIDTH)
104+
fill = max(dark_alpha, outline_alpha)
105+
alpha = int(max(0, min(255, disc_alpha * fill * 255)))
106+
if alpha > 0:
107+
pixels[y][x] = (0, 0, 0, alpha)
108+
return pixels
109+
110+
111+
def main():
112+
script_dir = os.path.dirname(os.path.abspath(__file__))
113+
repo_root = os.path.join(script_dir, '..', '..')
114+
icon_dir = os.path.join(repo_root, 'src', 'qt', 'res', 'icons')
115+
for frame in range(8):
116+
pixels = moon_frame(frame)
117+
png_data = make_png(pixels)
118+
filename = f'moon_{frame}.png'
119+
filepath = os.path.join(icon_dir, filename)
120+
with open(filepath, 'wb') as f:
121+
f.write(png_data)
122+
print(f' {filename} ({len(png_data)} bytes)')
123+
124+
125+
if __name__ == '__main__':
126+
main()

src/Makefile.qt.include

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ QT_FORMS_UI = \
3232
qt/forms/openuridialog.ui \
3333
qt/forms/optionsdialog.ui \
3434
qt/forms/overviewpage.ui \
35-
qt/forms/proposalwizard.ui \
35+
qt/forms/proposalcreate.ui \
36+
qt/forms/proposalresume.ui \
3637
qt/forms/psbtoperationsdialog.ui \
3738
qt/forms/qrdialog.ui \
3839
qt/forms/receivecoinsdialog.ui \
@@ -78,7 +79,8 @@ QT_MOC_CPP = \
7879
qt/moc_peertablemodel.cpp \
7980
qt/moc_peertablesortproxy.cpp \
8081
qt/moc_proposalmodel.cpp \
81-
qt/moc_proposalwizard.cpp \
82+
qt/moc_proposalcreate.cpp \
83+
qt/moc_proposalresume.cpp \
8284
qt/moc_psbtoperationsdialog.cpp \
8385
qt/moc_qrdialog.cpp \
8486
qt/moc_qrimagewidget.cpp \
@@ -160,8 +162,9 @@ BITCOIN_QT_H = \
160162
qt/paymentserver.h \
161163
qt/peertablemodel.h \
162164
qt/peertablesortproxy.h \
165+
qt/proposalcreate.h \
163166
qt/proposalmodel.h \
164-
qt/proposalwizard.h \
167+
qt/proposalresume.h \
165168
qt/psbtoperationsdialog.h \
166169
qt/qrdialog.h \
167170
qt/qrimagewidget.h \
@@ -211,6 +214,14 @@ QT_RES_ICONS = \
211214
qt/res/icons/hd_enabled.png \
212215
qt/res/icons/lock_closed.png \
213216
qt/res/icons/lock_open.png \
217+
qt/res/icons/moon_0.png \
218+
qt/res/icons/moon_1.png \
219+
qt/res/icons/moon_2.png \
220+
qt/res/icons/moon_3.png \
221+
qt/res/icons/moon_4.png \
222+
qt/res/icons/moon_5.png \
223+
qt/res/icons/moon_6.png \
224+
qt/res/icons/moon_7.png \
214225
qt/res/icons/proxy.png \
215226
qt/res/icons/remove.png \
216227
qt/res/icons/synced.png \
@@ -220,8 +231,10 @@ QT_RES_ICONS = \
220231
qt/res/icons/transaction3.png \
221232
qt/res/icons/transaction4.png \
222233
qt/res/icons/transaction5.png \
234+
qt/res/icons/transaction6.png \
223235
qt/res/icons/transaction_abandoned.png \
224236
qt/res/icons/transaction_locked.png \
237+
qt/res/icons/voting.png \
225238
qt/res/icons/warning.png
226239

227240
BITCOIN_QT_BASE_CPP = \
@@ -271,8 +284,9 @@ BITCOIN_QT_WALLET_CPP = \
271284
qt/openuridialog.cpp \
272285
qt/overviewpage.cpp \
273286
qt/paymentserver.cpp \
287+
qt/proposalcreate.cpp \
274288
qt/proposalmodel.cpp \
275-
qt/proposalwizard.cpp \
289+
qt/proposalresume.cpp \
276290
qt/psbtoperationsdialog.cpp \
277291
qt/qrdialog.cpp \
278292
qt/qrimagewidget.cpp \

src/governance/governance.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <governance/validators.h>
1616
#include <masternode/meta.h>
1717
#include <masternode/sync.h>
18+
#include <node/interface_ui.h>
1819
#include <protocol.h>
1920
#include <shutdown.h>
2021
#include <spork.h>
@@ -318,6 +319,7 @@ void CGovernanceManager::AddGovernanceObjectInternal(CGovernanceObject& insert_o
318319

319320
// SEND NOTIFICATION TO SCRIPT/ZMQ
320321
GetMainSignals().NotifyGovernanceObject(std::make_shared<const Governance::Object>(govobj->Object()), nHash.ToString());
322+
uiInterface.NotifyGovernanceChanged();
321323
}
322324

323325
void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, const CNode* pfrom)
@@ -530,19 +532,26 @@ std::vector<CGovernanceVote> CGovernanceManager::GetCurrentVotes(const uint256&
530532
return vecResult;
531533
}
532534

533-
void CGovernanceManager::GetAllNewerThan(std::vector<CGovernanceObject>& objs, int64_t nMoreThanTime) const
535+
void CGovernanceManager::GetAllNewerThan(std::vector<CGovernanceObject>& objs, int64_t nMoreThanTime,
536+
bool include_postponed) const
534537
{
535538
LOCK(cs_store);
536539

537540
for (const auto& [_, govobj] : mapObjects) {
538-
// IF THIS OBJECT IS OLDER THAN TIME, CONTINUE
539541
if (Assert(govobj)->GetCreationTime() < nMoreThanTime) {
540542
continue;
541543
}
542-
543-
// ADD GOVERNANCE OBJECT TO LIST
544544
objs.push_back(*govobj);
545545
}
546+
547+
if (include_postponed) {
548+
for (const auto& [_, govobj] : mapPostponedObjects) {
549+
if (Assert(govobj)->GetCreationTime() < nMoreThanTime) {
550+
continue;
551+
}
552+
objs.push_back(*govobj);
553+
}
554+
}
546555
}
547556

548557
bool CGovernanceManager::ConfirmInventoryRequest(const CInv& inv)

src/governance/governance.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ class CGovernanceManager : public GovernanceStore, public GovernanceSignerParent
291291
int64_t GetLastDiffTime() const { return nTimeLastDiff; }
292292
std::vector<CGovernanceVote> GetCurrentVotes(const uint256& nParentHash, const COutPoint& mnCollateralOutpointFilter) const
293293
EXCLUSIVE_LOCKS_REQUIRED(!cs_store);
294-
void GetAllNewerThan(std::vector<CGovernanceObject>& objs, int64_t nMoreThanTime) const
294+
void GetAllNewerThan(std::vector<CGovernanceObject>& objs, int64_t nMoreThanTime,
295+
bool include_postponed = false) const
295296
EXCLUSIVE_LOCKS_REQUIRED(!cs_store);
296297
void UpdateLastDiffTime(int64_t nTimeIn) { nTimeLastDiff = nTimeIn; }
297298

src/governance/object.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <core_io.h>
1616
#include <index/txindex.h>
1717
#include <logging.h>
18+
#include <node/interface_ui.h>
1819
#include <timedata.h>
1920
#include <util/time.h>
2021
#include <validation.h>
@@ -155,6 +156,7 @@ bool CGovernanceObject::ProcessVote(CMasternodeMetaMan& mn_metaman, CGovernanceM
155156
// SEND NOTIFICATION TO SCRIPT/ZMQ
156157
GetMainSignals().NotifyGovernanceVote(std::make_shared<CDeterministicMNList>(tip_mn_list),
157158
std::make_shared<const CGovernanceVote>(vote), vote.GetHash().ToString());
159+
uiInterface.NotifyGovernanceChanged();
158160
return true;
159161
}
160162

src/interfaces/node.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <net_types.h> // For banmap_t
1111
#include <netaddress.h> // For Network
1212
#include <netbase.h> // For ConnectionDirection
13+
#include <saltedhasher.h> // For StaticSaltedHasher
1314
#include <support/allocators/secure.h> // For SecureString
1415
#include <uint256.h>
1516
#include <util/settings.h> // For util::SettingsValue
@@ -23,6 +24,7 @@
2324
#include <stdint.h>
2425
#include <string>
2526
#include <tuple>
27+
#include <unordered_set>
2628
#include <vector>
2729

2830
class BanMan;
@@ -133,9 +135,15 @@ class GOV
133135
{
134136
public:
135137
virtual ~GOV() {}
136-
virtual void getAllNewerThan(std::vector<CGovernanceObject> &objs, int64_t nMoreThanTime) = 0;
137-
virtual int32_t getObjAbsYesCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) = 0;
138+
virtual void getAllNewerThan(std::vector<CGovernanceObject> &objs, int64_t nMoreThanTime, bool include_postponed = false) = 0;
139+
struct Votes {
140+
int32_t m_abs{0};
141+
int32_t m_no{0};
142+
int32_t m_yes{0};
143+
};
144+
virtual Votes getObjVotes(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) = 0;
138145
virtual bool getObjLocalValidity(const CGovernanceObject& obj, std::string& error, bool check_collateral) = 0;
146+
virtual bool existsObj(const uint256& hash) = 0;
139147
virtual bool isEnabled() = 0;
140148
virtual bool processVoteAndRelay(const CGovernanceVote& vote, std::string& error) = 0;
141149
struct GovernanceInfo {
@@ -151,6 +159,12 @@ class GOV
151159
int requiredConfs{6};
152160
};
153161
virtual GovernanceInfo getGovernanceInfo() = 0;
162+
virtual std::optional<int32_t> getProposalFundedHeight(const uint256& proposal_hash) = 0;
163+
struct FundableResult {
164+
std::unordered_set<uint256, StaticSaltedHasher> hashes;
165+
CAmount allocated{0};
166+
};
167+
virtual FundableResult getFundableProposalHashes() = 0;
154168
virtual std::optional<CGovernanceObject> createProposal(int32_t revision, int64_t created_time,
155169
const std::string& data_hex, std::string& error) = 0;
156170
virtual bool submitProposal(const uint256& parent, int32_t revision, int64_t created_time, const std::string& data_hex,
@@ -175,6 +189,7 @@ class Sync
175189
public:
176190
virtual ~Sync() {}
177191
virtual bool isBlockchainSynced() = 0;
192+
virtual bool isGovernanceSynced() = 0;
178193
virtual bool isSynced() = 0;
179194
virtual std::string getSyncStatus() = 0;
180195
virtual void setContext(node::NodeContext* context) {}
@@ -466,6 +481,10 @@ class Node
466481
std::function<void(SynchronizationState, interfaces::BlockTip tip, double verification_progress)>;
467482
virtual std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) = 0;
468483

484+
//! Register handler for governance data messages.
485+
using NotifyGovernanceChangedFn = std::function<void()>;
486+
virtual std::unique_ptr<Handler> handleNotifyGovernanceChanged(NotifyGovernanceChangedFn fn) = 0;
487+
469488
//! Register handler for masternode list update messages.
470489
using NotifyMasternodeListChangedFn =
471490
std::function<void(const CDeterministicMNList& newList,

src/interfaces/wallet.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <consensus/amount.h> // For CAmount
99
#include <fs.h>
10+
#include <governance/common.h>
1011
#include <interfaces/chain.h> // For ChainClient
1112
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
1213
#include <script/standard.h> // For CTxDestination
@@ -351,6 +352,9 @@ class Wallet
351352
using CanGetAddressesChangedFn = std::function<void()>;
352353
virtual std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) = 0;
353354

355+
//! Get governance objects stored in the wallet.
356+
virtual std::vector<Governance::Object> getGovernanceObjects() = 0;
357+
354358
//! Prepare a governance proposal (burns fee).
355359
virtual bool prepareProposal(const uint256& govobj_hash, CAmount fee, int32_t revision, int64_t created_time,
356360
const std::string& data_hex, const COutPoint& outpoint,

src/node/interface_ui.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct UISignals {
2323
boost::signals2::signal<CClientUIInterface::NotifyBlockTipSig> NotifyBlockTip;
2424
boost::signals2::signal<CClientUIInterface::NotifyChainLockSig> NotifyChainLock;
2525
boost::signals2::signal<CClientUIInterface::NotifyHeaderTipSig> NotifyHeaderTip;
26+
boost::signals2::signal<CClientUIInterface::NotifyGovernanceChangedSig> NotifyGovernanceChanged;
2627
boost::signals2::signal<CClientUIInterface::NotifyMasternodeListChangedSig> NotifyMasternodeListChanged;
2728
boost::signals2::signal<CClientUIInterface::NotifyAdditionalDataSyncProgressChangedSig> NotifyAdditionalDataSyncProgressChanged;
2829
boost::signals2::signal<CClientUIInterface::BannedListChangedSig> BannedListChanged;
@@ -46,6 +47,7 @@ ADD_SIGNALS_IMPL_WRAPPER(ShowProgress);
4647
ADD_SIGNALS_IMPL_WRAPPER(NotifyBlockTip);
4748
ADD_SIGNALS_IMPL_WRAPPER(NotifyChainLock);
4849
ADD_SIGNALS_IMPL_WRAPPER(NotifyHeaderTip);
50+
ADD_SIGNALS_IMPL_WRAPPER(NotifyGovernanceChanged);
4951
ADD_SIGNALS_IMPL_WRAPPER(NotifyMasternodeListChanged);
5052
ADD_SIGNALS_IMPL_WRAPPER(NotifyAdditionalDataSyncProgressChanged);
5153
ADD_SIGNALS_IMPL_WRAPPER(BannedListChanged);
@@ -61,6 +63,7 @@ void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, b
6163
void CClientUIInterface::NotifyBlockTip(SynchronizationState s, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(s, i); }
6264
void CClientUIInterface::NotifyChainLock(const std::string& bestChainLockHash, int bestChainLockHeight) { return g_ui_signals.NotifyChainLock(bestChainLockHash, bestChainLockHeight); }
6365
void CClientUIInterface::NotifyHeaderTip(SynchronizationState s, const CBlockIndex* i) { return g_ui_signals.NotifyHeaderTip(s, i); }
66+
void CClientUIInterface::NotifyGovernanceChanged() { return g_ui_signals.NotifyGovernanceChanged(); }
6467
void CClientUIInterface::NotifyMasternodeListChanged(const CDeterministicMNList& list, const CBlockIndex* i) { return g_ui_signals.NotifyMasternodeListChanged(list, i); }
6568
void CClientUIInterface::NotifyAdditionalDataSyncProgressChanged(double nSyncProgress) { return g_ui_signals.NotifyAdditionalDataSyncProgressChanged(nSyncProgress); }
6669
void CClientUIInterface::BannedListChanged() { return g_ui_signals.BannedListChanged(); }

src/node/interface_ui.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ class CClientUIInterface
115115
/** Masternode list has changed */
116116
ADD_SIGNALS_DECL_WRAPPER(NotifyMasternodeListChanged, void, const CDeterministicMNList&, const CBlockIndex*);
117117

118+
/** Governance data changed */
119+
ADD_SIGNALS_DECL_WRAPPER(NotifyGovernanceChanged, void);
120+
118121
/** Additional data sync progress changed */
119122
ADD_SIGNALS_DECL_WRAPPER(NotifyAdditionalDataSyncProgressChanged, void, double nSyncProgress);
120123

0 commit comments

Comments
 (0)