44#include " masternode/activemasternode.h"
55#include " clientmodel.h"
66#include " clientversion.h"
7+ #include " coins.h"
78#include " guiutil.h"
89#include " init.h"
910#include " masternode/masternode-sync.h"
1011#include " netbase.h"
1112#include " sync.h"
13+ #include " validation.h"
1214#include " wallet/wallet.h"
1315#include " walletmodel.h"
1416
@@ -49,6 +51,9 @@ MasternodeList::MasternodeList(const PlatformStyle* platformStyle, QWidget* pare
4951 int columnNextPaymentWidth = 100 ;
5052 int columnPayeeWidth = 130 ;
5153 int columnOperatorRewardWidth = 130 ;
54+ int columnCollateralWidth = 130 ;
55+ int columnOwnerWidth = 130 ;
56+ int columnVotingWidth = 130 ;
5257
5358 ui->tableWidgetMasternodesDIP3 ->setColumnWidth (0 , columnAddressWidth);
5459 ui->tableWidgetMasternodesDIP3 ->setColumnWidth (1 , columnStatusWidth);
@@ -58,11 +63,14 @@ MasternodeList::MasternodeList(const PlatformStyle* platformStyle, QWidget* pare
5863 ui->tableWidgetMasternodesDIP3 ->setColumnWidth (5 , columnNextPaymentWidth);
5964 ui->tableWidgetMasternodesDIP3 ->setColumnWidth (6 , columnPayeeWidth);
6065 ui->tableWidgetMasternodesDIP3 ->setColumnWidth (7 , columnOperatorRewardWidth);
66+ ui->tableWidgetMasternodesDIP3 ->setColumnWidth (8 , columnCollateralWidth);
67+ ui->tableWidgetMasternodesDIP3 ->setColumnWidth (9 , columnOwnerWidth);
68+ ui->tableWidgetMasternodesDIP3 ->setColumnWidth (10 , columnVotingWidth);
6169
6270 // dummy column for proTxHash
6371 // TODO use a proper table model for the MN list
64- ui->tableWidgetMasternodesDIP3 ->insertColumn (8 );
65- ui->tableWidgetMasternodesDIP3 ->setColumnHidden (8 , true );
72+ ui->tableWidgetMasternodesDIP3 ->insertColumn (11 );
73+ ui->tableWidgetMasternodesDIP3 ->setColumnHidden (11 , true );
6674
6775 ui->tableWidgetMasternodesDIP3 ->setContextMenuPolicy (Qt::CustomContextMenu);
6876
@@ -132,7 +140,8 @@ void MasternodeList::updateDIP3ListScheduled()
132140 fFilterUpdatedDIP3 = false ;
133141 }
134142 } else if (mnListChanged) {
135- int64_t nSecondsToWait = nTimeUpdatedDIP3 - GetTime () + MASTERNODELIST_UPDATE_SECONDS;
143+ int64_t nMnListUpdateSecods = masternodeSync.IsBlockchainSynced () ? MASTERNODELIST_UPDATE_SECONDS : MASTERNODELIST_UPDATE_SECONDS*10 ;
144+ int64_t nSecondsToWait = nTimeUpdatedDIP3 - GetTime () + nMnListUpdateSecods;
136145
137146 if (nSecondsToWait <= 0 ) {
138147 updateDIP3List ();
@@ -147,6 +156,22 @@ void MasternodeList::updateDIP3List()
147156 return ;
148157 }
149158
159+ auto mnList = clientModel->getMasternodeList ();
160+ std::map<uint256, CTxDestination> mapCollateralDests;
161+
162+ {
163+ // Get all UTXOs for each MN collateral in one go so that we can reduce locking overhead for cs_main
164+ // We also do this outside of the below Qt list update loop to reduce cs_main locking time to a minimum
165+ LOCK (cs_main);
166+ mnList.ForEachMN (false , [&](const CDeterministicMNCPtr& dmn) {
167+ CTxDestination collateralDest;
168+ Coin coin;
169+ if (GetUTXOCoin (dmn->collateralOutpoint , coin) && ExtractDestination (coin.out .scriptPubKey , collateralDest)) {
170+ mapCollateralDests.emplace (dmn->proTxHash , collateralDest);
171+ }
172+ });
173+ }
174+
150175 LOCK (cs_dip3list);
151176
152177 QString strToFilter;
@@ -155,7 +180,6 @@ void MasternodeList::updateDIP3List()
155180 ui->tableWidgetMasternodesDIP3 ->clearContents ();
156181 ui->tableWidgetMasternodesDIP3 ->setRowCount (0 );
157182
158- auto mnList = clientModel->getMasternodeList ();
159183 nTimeUpdatedDIP3 = GetTime ();
160184
161185 auto projectedPayees = mnList.GetProjectedMNPayees (mnList.GetValidMNsCount ());
@@ -193,17 +217,15 @@ void MasternodeList::updateDIP3List()
193217 QTableWidgetItem* nextPaymentItem = new QTableWidgetItem (nextPayments.count (dmn->proTxHash ) ? QString::number (nextPayments[dmn->proTxHash ]) : tr (" UNKNOWN" ));
194218
195219 CTxDestination payeeDest;
196- QString payeeStr;
220+ QString payeeStr = tr ( " UNKNOWN " ) ;
197221 if (ExtractDestination (dmn->pdmnState ->scriptPayout , payeeDest)) {
198222 payeeStr = QString::fromStdString (CBitcoinAddress (payeeDest).ToString ());
199- } else {
200- payeeStr = tr (" UNKNOWN" );
201223 }
202224 QTableWidgetItem* payeeItem = new QTableWidgetItem (payeeStr);
203225
204- QString operatorRewardStr;
226+ QString operatorRewardStr = tr ( " NONE " ) ;
205227 if (dmn->nOperatorReward ) {
206- operatorRewardStr + = QString::number (dmn->nOperatorReward / 100.0 , ' f' , 2 ) + " % " ;
228+ operatorRewardStr = QString::number (dmn->nOperatorReward / 100.0 , ' f' , 2 ) + " % " ;
207229
208230 if (dmn->pdmnState ->scriptOperatorPayout != CScript ()) {
209231 CTxDestination operatorDest;
@@ -215,10 +237,22 @@ void MasternodeList::updateDIP3List()
215237 } else {
216238 operatorRewardStr += tr (" but not claimed" );
217239 }
218- } else {
219- operatorRewardStr = tr (" NONE" );
220240 }
221241 QTableWidgetItem* operatorRewardItem = new QTableWidgetItem (operatorRewardStr);
242+
243+ QString collateralStr = tr (" UNKNOWN" );
244+ auto collateralDestIt = mapCollateralDests.find (dmn->proTxHash );
245+ if (collateralDestIt != mapCollateralDests.end ()) {
246+ collateralStr = QString::fromStdString (CBitcoinAddress (collateralDestIt->second ).ToString ());
247+ }
248+ QTableWidgetItem* collateralItem = new QTableWidgetItem (collateralStr);
249+
250+ QString ownerStr = QString::fromStdString (CBitcoinAddress (dmn->pdmnState ->keyIDOwner ).ToString ());
251+ QTableWidgetItem* ownerItem = new QTableWidgetItem (ownerStr);
252+
253+ QString votingStr = QString::fromStdString (CBitcoinAddress (dmn->pdmnState ->keyIDVoting ).ToString ());
254+ QTableWidgetItem* votingItem = new QTableWidgetItem (votingStr);
255+
222256 QTableWidgetItem* proTxHashItem = new QTableWidgetItem (QString::fromStdString (dmn->proTxHash .ToString ()));
223257
224258 if (strCurrentFilterDIP3 != " " ) {
@@ -230,6 +264,9 @@ void MasternodeList::updateDIP3List()
230264 nextPaymentItem->text () + " " +
231265 payeeItem->text () + " " +
232266 operatorRewardItem->text () + " " +
267+ collateralItem->text () + " " +
268+ ownerItem->text () + " " +
269+ votingItem->text () + " " +
233270 proTxHashItem->text ();
234271 if (!strToFilter.contains (strCurrentFilterDIP3)) return ;
235272 }
@@ -243,7 +280,10 @@ void MasternodeList::updateDIP3List()
243280 ui->tableWidgetMasternodesDIP3 ->setItem (0 , 5 , nextPaymentItem);
244281 ui->tableWidgetMasternodesDIP3 ->setItem (0 , 6 , payeeItem);
245282 ui->tableWidgetMasternodesDIP3 ->setItem (0 , 7 , operatorRewardItem);
246- ui->tableWidgetMasternodesDIP3 ->setItem (0 , 8 , proTxHashItem);
283+ ui->tableWidgetMasternodesDIP3 ->setItem (0 , 8 , collateralItem);
284+ ui->tableWidgetMasternodesDIP3 ->setItem (0 , 9 , ownerItem);
285+ ui->tableWidgetMasternodesDIP3 ->setItem (0 , 10 , votingItem);
286+ ui->tableWidgetMasternodesDIP3 ->setItem (0 , 11 , proTxHashItem);
247287 });
248288
249289 ui->countLabelDIP3 ->setText (QString::number (ui->tableWidgetMasternodesDIP3 ->rowCount ()));
@@ -282,7 +322,7 @@ CDeterministicMNCPtr MasternodeList::GetSelectedDIP3MN()
282322
283323 QModelIndex index = selected.at (0 );
284324 int nSelectedRow = index.row ();
285- strProTxHash = ui->tableWidgetMasternodesDIP3 ->item (nSelectedRow, 8 )->text ().toStdString ();
325+ strProTxHash = ui->tableWidgetMasternodesDIP3 ->item (nSelectedRow, 11 )->text ().toStdString ();
286326 }
287327
288328 uint256 proTxHash;
0 commit comments