PIVX Core  5.6.99
P2P Digital Currency
mnmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2022 The PIVX Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "mnmodel.h"
6 
7 #include "coincontrol.h"
8 #include "guitransactionsutils.h"
9 #include "masternode.h"
10 #include "masternodeman.h"
11 #include "net.h" // for validateMasternodeIP
12 #include "primitives/transaction.h"
13 #include "qt/bitcoinunits.h"
14 #include "qt/optionsmodel.h"
15 #include "qt/walletmodel.h"
18 #include "uint256.h"
19 
20 #include <QFile>
21 #include <QHostAddress>
22 
23 MNModel::MNModel(QObject *parent) : QAbstractTableModel(parent) {}
24 
26 {
27  updateMNList();
28 }
29 
31 {
32  int mnMinConf = getMasternodeCollateralMinConf();
33  int end = nodes.size();
34  nodes.clear();
35  collateralTxAccepted.clear();
37  int nIndex;
38  if (!mne.castOutputIndex(nIndex))
39  continue;
40  const uint256& txHash = uint256S(mne.getTxHash());
41  CTxIn txIn(txHash, uint32_t(nIndex));
42  CMasternode* pmn = mnodeman.Find(txIn.prevout);
43  if (!pmn) {
44  pmn = new CMasternode();
45  pmn->vin = txIn;
46  }
47  nodes.insert(QString::fromStdString(mne.getAlias()), std::make_pair(QString::fromStdString(mne.getIp()), pmn));
48  if (walletModel) {
49  collateralTxAccepted.insert(mne.getTxHash(), walletModel->getWalletTxDepth(txHash) >= mnMinConf);
50  }
51  }
52  Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(end, 5, QModelIndex()) );
53 }
54 
55 int MNModel::rowCount(const QModelIndex &parent) const
56 {
57  if (parent.isValid())
58  return 0;
59  return nodes.size();
60 }
61 
62 int MNModel::columnCount(const QModelIndex &parent) const
63 {
64  if (parent.isValid())
65  return 0;
66  return 6;
67 }
68 
69 
70 QVariant MNModel::data(const QModelIndex &index, int role) const
71 {
72  if (!index.isValid())
73  return QVariant();
74 
75  // rec could be null, always verify it.
76  CMasternode* rec = static_cast<CMasternode*>(index.internalPointer());
77  bool isAvailable = rec;
78  int row = index.row();
79  if (role == Qt::DisplayRole || role == Qt::EditRole) {
80  switch (index.column()) {
81  case ALIAS:
82  return nodes.uniqueKeys().value(row);
83  case ADDRESS:
84  return nodes.values().value(row).first;
85  case PUB_KEY:
86  return (isAvailable) ? QString::fromStdString(nodes.values().value(row).second->pubKeyMasternode.GetHash().GetHex()) : "Not available";
87  case COLLATERAL_ID:
88  return (isAvailable) ? QString::fromStdString(rec->vin.prevout.hash.GetHex()) : "Not available";
90  return (isAvailable) ? QString::number(rec->vin.prevout.n) : "Not available";
91  case STATUS: {
92  std::pair<QString, CMasternode*> pair = nodes.values().value(row);
93  std::string status = "MISSING";
94  if (pair.second) {
95  status = pair.second->Status();
96  // Quick workaround to the current Masternode status types.
97  // If the status is REMOVE and there is no pubkey associated to the Masternode
98  // means that the MN is not in the network list and was created in
99  // updateMNList(). Which.. denotes a not started masternode.
100  // This will change in the future with the MasternodeWrapper introduction.
101  if (status == "REMOVE" && !pair.second->pubKeyCollateralAddress.IsValid()) {
102  return "MISSING";
103  }
104  }
105  return QString::fromStdString(status);
106  }
107  case PRIV_KEY: {
108  if (isAvailable) {
110  if (mne.getTxHash().compare(rec->vin.prevout.hash.GetHex()) == 0) {
111  return QString::fromStdString(mne.getPrivKey());
112  }
113  }
114  }
115  return "Not available";
116  }
118  return isAvailable && collateralTxAccepted.value(rec->vin.prevout.hash.GetHex());
119  }
120  }
121  }
122  return QVariant();
123 }
124 
125 QModelIndex MNModel::index(int row, int column, const QModelIndex& parent) const
126 {
127  Q_UNUSED(parent);
128  std::pair<QString, CMasternode*> pair = nodes.values().value(row);
129  CMasternode* data = pair.second;
130  if (data) {
131  return createIndex(row, column, data);
132  } else if (!pair.first.isEmpty()) {
133  return createIndex(row, column, nullptr);
134  } else {
135  return QModelIndex();
136  }
137 }
138 
139 
140 bool MNModel::removeMn(const QModelIndex& modelIndex)
141 {
142  QString alias = modelIndex.data(Qt::DisplayRole).toString();
143  int idx = modelIndex.row();
144  beginRemoveRows(QModelIndex(), idx, idx);
145  nodes.take(alias);
146  endRemoveRows();
147  Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, 5, QModelIndex()) );
148  return true;
149 }
150 
152 {
153  beginInsertRows(QModelIndex(), nodes.size(), nodes.size());
154  int nIndex;
155  if (!mne->castOutputIndex(nIndex))
156  return false;
157 
158  CMasternode* pmn = mnodeman.Find(COutPoint(uint256S(mne->getTxHash()), uint32_t(nIndex)));
159  nodes.insert(QString::fromStdString(mne->getAlias()), std::make_pair(QString::fromStdString(mne->getIp()), pmn));
160  endInsertRows();
161  return true;
162 }
163 
164 int MNModel::getMNState(const QString& mnAlias)
165 {
166  QMap<QString, std::pair<QString, CMasternode*>>::const_iterator it = nodes.find(mnAlias);
167  if (it != nodes.end()) return it.value().second->GetActiveState();
168  throw std::runtime_error(std::string("Masternode alias not found"));
169 }
170 
171 bool MNModel::isMNInactive(const QString& mnAlias)
172 {
173  int activeState = getMNState(mnAlias);
174  return activeState == CMasternode::MASTERNODE_EXPIRED || activeState == CMasternode::MASTERNODE_REMOVE;
175 }
176 
177 bool MNModel::isMNActive(const QString& mnAlias)
178 {
179  int activeState = getMNState(mnAlias);
180  return activeState == CMasternode::MASTERNODE_PRE_ENABLED || activeState == CMasternode::MASTERNODE_ENABLED;
181 }
182 
183 bool MNModel::isMNCollateralMature(const QString& mnAlias)
184 {
185  QMap<QString, std::pair<QString, CMasternode*>>::const_iterator it = nodes.find(mnAlias);
186  if (it != nodes.end()) return collateralTxAccepted.value(it.value().second->vin.prevout.hash.GetHex());
187  throw std::runtime_error(std::string("Masternode alias not found"));
188 }
189 
191 {
193 }
194 
195 bool MNModel::validateMNIP(const QString& addrStr)
196 {
197  return validateMasternodeIP(addrStr.toStdString());
198 }
199 
201 {
203 }
204 
206 {
208 }
209 
211  const QString& alias,
212  const QString& addr,
213  COutPoint& ret_outpoint,
214  QString& ret_error)
215 {
216  SendCoinsRecipient sendCoinsRecipient(addr, alias, getMNCollateralRequiredAmount(), "");
217 
218  // Send the 10 tx to one of your address
219  QList<SendCoinsRecipient> recipients;
220  recipients.append(sendCoinsRecipient);
221  WalletModelTransaction currentTransaction(recipients);
222  WalletModel::SendCoinsReturn prepareStatus;
223 
224  // no P2CS delegations
225  prepareStatus = walletModel->prepareTransaction(&currentTransaction, coinControl, false);
226  QString returnMsg = tr("Unknown error");
227  // process prepareStatus and on error generate message shown to user
230  prepareStatus,
231  walletModel,
232  informType, // this flag is not needed
234  currentTransaction.getTransactionFee()),
235  true
236  );
237 
238  if (prepareStatus.status != WalletModel::OK) {
239  ret_error = tr("Prepare master node failed.\n\n%1\n").arg(returnMsg);
240  return false;
241  }
242 
243  WalletModel::SendCoinsReturn sendStatus = walletModel->sendCoins(currentTransaction);
244  // process sendStatus and on error generate message shown to user
245  returnMsg = GuiTransactionsUtils::ProcessSendCoinsReturn(sendStatus, walletModel, informType);
246 
247  if (sendStatus.status != WalletModel::OK) {
248  ret_error = tr("Cannot send collateral transaction.\n\n%1").arg(returnMsg);
249  return false;
250  }
251 
252  // look for the tx index of the collateral
253  CTransactionRef walletTx = currentTransaction.getTransaction();
254  std::string txID = walletTx->GetHash().GetHex();
255  int indexOut = -1;
256  for (int i=0; i < (int)walletTx->vout.size(); i++) {
257  const CTxOut& out = walletTx->vout[i];
258  if (out.nValue == getMNCollateralRequiredAmount()) {
259  indexOut = i;
260  break;
261  }
262  }
263  if (indexOut == -1) {
264  ret_error = tr("Invalid collateral output index");
265  return false;
266  }
267  // save the collateral outpoint
268  ret_outpoint = COutPoint(walletTx->GetHash(), indexOut);
269  return true;
270 }
271 
272 bool MNModel::startLegacyMN(const CMasternodeConfig::CMasternodeEntry& mne, int chainHeight, std::string& strError)
273 {
275  if (!CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb, false, chainHeight))
276  return false;
277 
281  }
282  mnb.Relay();
283  return true;
284 }
285 
286 void MNModel::startAllLegacyMNs(bool onlyMissing, int& amountOfMnFailed, int& amountOfMnStarted,
287  std::string* aliasFilter, std::string* error_ret)
288 {
289  for (const auto& mne : masternodeConfig.getEntries()) {
290  if (!aliasFilter) {
291  // Check for missing only
292  QString mnAlias = QString::fromStdString(mne.getAlias());
293  if (onlyMissing && !isMNInactive(mnAlias)) {
294  if (!isMNActive(mnAlias))
295  amountOfMnFailed++;
296  continue;
297  }
298 
299  if (!isMNCollateralMature(mnAlias)) {
300  amountOfMnFailed++;
301  continue;
302  }
303  } else if (*aliasFilter != mne.getAlias()){
304  continue;
305  }
306 
307  std::string ret_str;
308  if (!startLegacyMN(mne, walletModel->getLastBlockProcessedNum(), ret_str)) {
309  amountOfMnFailed++;
310  if (error_ret) *error_ret = ret_str;
311  } else {
312  amountOfMnStarted++;
313  }
314  }
315 }
316 
317 // Future: remove after v6.0
319  const std::string& alias,
320  std::string& serviceAddr,
321  const std::string& port,
322  const std::string& mnKeyString,
323  QString& ret_error)
324 {
325  // Update the conf file
326  QString strConfFileQt(PIVX_MASTERNODE_CONF_FILENAME);
327  std::string strConfFile = strConfFileQt.toStdString();
328  std::string strDataDir = GetDataDir().string();
329  fs::path conf_file_path(strConfFile);
330  if (strConfFile != conf_file_path.filename().string()) {
331  throw std::runtime_error(strprintf(_("%s %s resides outside data directory %s"), strConfFile, strConfFile, strDataDir));
332  }
333 
334  fs::path pathBootstrap = GetDataDir() / strConfFile;
335  if (!fs::exists(pathBootstrap)) {
336  ret_error = tr("%1 file doesn't exists").arg(strConfFileQt);
337  return nullptr;
338  }
339 
340  fs::path pathMasternodeConfigFile = GetMasternodeConfigFile();
341  fsbridge::ifstream streamConfig(pathMasternodeConfigFile);
342 
343  if (!streamConfig.good()) {
344  ret_error = tr("Invalid %1 file").arg(strConfFileQt);
345  return nullptr;
346  }
347 
348  int linenumber = 1;
349  std::string lineCopy;
350  for (std::string line; std::getline(streamConfig, line); linenumber++) {
351  if (line.empty()) continue;
352 
353  std::istringstream iss(line);
354  std::string comment, alias, ip, privKey, txHash, outputIndex;
355 
356  if (iss >> comment) {
357  if (comment.at(0) == '#') continue;
358  iss.str(line);
359  iss.clear();
360  }
361 
362  if (!(iss >> alias >> ip >> privKey >> txHash >> outputIndex)) {
363  iss.str(line);
364  iss.clear();
365  if (!(iss >> alias >> ip >> privKey >> txHash >> outputIndex)) {
366  streamConfig.close();
367  ret_error = tr("Error parsing %1 file").arg(strConfFileQt);
368  return nullptr;
369  }
370  }
371  lineCopy += line + "\n";
372  }
373 
374  if (lineCopy.empty()) {
375  lineCopy = "# Masternode config file\n"
376  "# Format: alias IP:port masternodeprivkey collateral_output_txid collateral_output_index\n"
377  "# Example: mn1 127.0.0.2:51472 93HaYBVUCYjEMeeH1Y4sBGLALQZE1Yc1K64xiqgX37tGBDQL8Xg 2bcd3c84c84f87eaa86e4e56834c92927a07f9e18718810b92e0d0324456a67c 0"
378  "#";
379  }
380  lineCopy += "\n";
381 
382  streamConfig.close();
383 
384  std::string txID = collateralOut.hash.ToString();
385  std::string indexOutStr = std::to_string(collateralOut.n);
386 
387  // Check IP address type
388  QHostAddress hostAddress(QString::fromStdString(serviceAddr));
389  QAbstractSocket::NetworkLayerProtocol layerProtocol = hostAddress.protocol();
390  if (layerProtocol == QAbstractSocket::IPv6Protocol) {
391  serviceAddr = "["+serviceAddr+"]";
392  }
393 
394  fs::path pathConfigFile = AbsPathForConfigVal(fs::path("masternode_temp.conf"));
395  FILE* configFile = fopen(pathConfigFile.string().c_str(), "w");
396  lineCopy += alias+" "+serviceAddr+":"+port+" "+mnKeyString+" "+txID+" "+indexOutStr+"\n";
397  fwrite(lineCopy.c_str(), std::strlen(lineCopy.c_str()), 1, configFile);
398  fclose(configFile);
399 
400  fs::path pathOldConfFile = AbsPathForConfigVal(fs::path("old_masternode.conf"));
401  if (fs::exists(pathOldConfFile)) {
402  fs::remove(pathOldConfFile);
403  }
404  rename(pathMasternodeConfigFile, pathOldConfFile);
405 
406  fs::path pathNewConfFile = AbsPathForConfigVal(fs::path(strConfFile));
407  rename(pathConfigFile, pathNewConfFile);
408 
409  auto ret_mn_entry = masternodeConfig.add(alias, serviceAddr+":"+port, mnKeyString, txID, indexOutStr);
410 
411  // Lock collateral output
412  walletModel->lockCoin(collateralOut.hash, collateralOut.n);
413  return ret_mn_entry;
414 }
415 
416 // Future: remove after v6.0
417 bool MNModel::removeLegacyMN(const std::string& alias_to_remove, const std::string& tx_id, unsigned int out_index, QString& ret_error)
418 {
419  QString strConfFileQt(PIVX_MASTERNODE_CONF_FILENAME);
420  std::string strConfFile = strConfFileQt.toStdString();
421  std::string strDataDir = GetDataDir().string();
422  fs::path conf_file_path(strConfFile);
423  if (strConfFile != conf_file_path.filename().string()) {
424  throw std::runtime_error(strprintf(_("%s %s resides outside data directory %s"), strConfFile, strConfFile, strDataDir));
425  }
426 
427  fs::path pathBootstrap = GetDataDir() / strConfFile;
428  if (!fs::exists(pathBootstrap)) {
429  ret_error = tr("%1 file doesn't exists").arg(strConfFileQt);
430  return false;
431  }
432 
433  fs::path pathMasternodeConfigFile = GetMasternodeConfigFile();
434  fsbridge::ifstream streamConfig(pathMasternodeConfigFile);
435 
436  if (!streamConfig.good()) {
437  ret_error = tr("Invalid %1 file").arg(strConfFileQt);
438  return false;
439  }
440 
441  int lineNumToRemove = -1;
442  int linenumber = 1;
443  std::string lineCopy;
444  for (std::string line; std::getline(streamConfig, line); linenumber++) {
445  if (line.empty()) continue;
446 
447  std::istringstream iss(line);
448  std::string comment, alias, ip, privKey, txHash, outputIndex;
449 
450  if (iss >> comment) {
451  if (comment.at(0) == '#') continue;
452  iss.str(line);
453  iss.clear();
454  }
455 
456  if (!(iss >> alias >> ip >> privKey >> txHash >> outputIndex)) {
457  iss.str(line);
458  iss.clear();
459  if (!(iss >> alias >> ip >> privKey >> txHash >> outputIndex)) {
460  streamConfig.close();
461  ret_error = tr("Error parsing %1 file").arg(strConfFileQt);
462  return false;
463  }
464  }
465 
466  if (alias_to_remove == alias) {
467  lineNumToRemove = linenumber;
468  } else
469  lineCopy += line + "\n";
470 
471  }
472 
473  if (lineCopy.empty()) {
474  lineCopy = "# Masternode config file\n"
475  "# Format: alias IP:port masternodeprivkey collateral_output_txid collateral_output_index\n"
476  "# Example: mn1 127.0.0.2:51472 93HaYBVUCYjEMeeH1Y4sBGLALQZE1Yc1K64xiqgX37tGBDQL8Xg 2bcd3c84c84f87eaa86e4e56834c92927a07f9e18718810b92e0d0324456a67c 0\n";
477  }
478 
479  streamConfig.close();
480 
481  if (lineNumToRemove == -1) {
482  ret_error = tr("MN alias %1 not found in %2 file").arg(QString::fromStdString(alias_to_remove)).arg(strConfFileQt);
483  return false;
484  }
485 
486  // Update file
487  fs::path pathConfigFile = AbsPathForConfigVal(fs::path("masternode_temp.conf"));
488  FILE* configFile = fsbridge::fopen(pathConfigFile, "w");
489  fwrite(lineCopy.c_str(), std::strlen(lineCopy.c_str()), 1, configFile);
490  fclose(configFile);
491 
492  fs::path pathOldConfFile = AbsPathForConfigVal(fs::path("old_masternode.conf"));
493  if (fs::exists(pathOldConfFile)) {
494  fs::remove(pathOldConfFile);
495  }
496  rename(pathMasternodeConfigFile, pathOldConfFile);
497 
498  fs::path pathNewConfFile = AbsPathForConfigVal(fs::path(strConfFile));
499  rename(pathConfigFile, pathNewConfFile);
500 
501  // Unlock collateral
502  walletModel->unlockCoin(uint256S(tx_id), out_index);
503  // Remove alias
504  masternodeConfig.remove(alias_to_remove);
505  return true;
506 }
507 
509 {
510  this->coinControl = coinControl;
511 }
512 
514 {
515  coinControl = nullptr;
516 }
CService ip(uint32_t i)
Definition: DoS_tests.cpp:39
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
const CChainParams & Params()
Return the currently selected parameters.
uint256 hash
Definition: transaction.h:35
uint32_t n
Definition: transaction.h:36
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
bool EnableHotColdMasterNode(CTxIn &vin, CService &addr)
Enable cold wallet mode (run a Masternode with no funds)
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:72
MessageBoxFlags
Flags for CClientUIInterface::ThreadSafeMessageBox.
Definition: guiinterface.h:35
Coin Control Features.
Definition: coincontrol.h:34
static bool Create(const CTxIn &vin, const CService &service, const CKey &keyCollateralAddressNew, const CPubKey &pubKeyCollateralAddressNew, const CKey &keyMasternodeNew, const CPubKey &pubKeyMasternodeNew, std::string &strErrorRet, CMasternodeBroadcast &mnbRet)
Create Masternode broadcast, needs to be relayed manually after that.
Definition: masternode.cpp:290
const std::string & getTxHash() const
const std::string & getOutputIndex() const
const std::string & getIp() const
bool castOutputIndex(int &n) const
const std::string & getPrivKey() const
const std::string & getAlias() const
void remove(std::string alias)
CMasternodeConfig::CMasternodeEntry * add(std::string alias, std::string ip, std::string privKey, std::string txHash, std::string outputIndex)
std::vector< CMasternodeEntry > getEntries()
CService addr
Definition: masternode.h:97
CTxIn vin
Definition: masternode.h:96
CPubKey GetPubKey() const
Definition: masternode.h:116
@ MASTERNODE_ENABLED
Definition: masternode.h:90
@ MASTERNODE_REMOVE
Definition: masternode.h:92
@ MASTERNODE_EXPIRED
Definition: masternode.h:91
@ MASTERNODE_PRE_ENABLED
Definition: masternode.h:89
void UpdateMasternodeList(CMasternodeBroadcast &mnb)
Update masternode list and maps using provided CMasternodeBroadcast.
CMasternode * Find(const COutPoint &collateralOut)
Find an entry.
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
An input of a transaction.
Definition: transaction.h:94
COutPoint prevout
Definition: transaction.h:96
An output of a transaction.
Definition: transaction.h:137
CAmount nValue
Definition: transaction.h:139
MNModel(QObject *parent)
Definition: mnmodel.cpp:23
int getMNState(const QString &mnAlias)
Definition: mnmodel.cpp:164
QMap< QString, std::pair< QString, CMasternode * > > nodes
Definition: mnmodel.h:87
bool startLegacyMN(const CMasternodeConfig::CMasternodeEntry &mne, int chainHeight, std::string &strError)
Definition: mnmodel.cpp:272
bool createMNCollateral(const QString &alias, const QString &addr, COutPoint &ret_outpoint, QString &ret_error)
Definition: mnmodel.cpp:210
bool removeMn(const QModelIndex &index)
Definition: mnmodel.cpp:140
bool isMNActive(const QString &mnAlias)
Definition: mnmodel.cpp:177
CAmount getMNCollateralRequiredAmount()
Definition: mnmodel.cpp:200
static bool validateMNIP(const QString &addrStr)
Definition: mnmodel.cpp:195
void startAllLegacyMNs(bool onlyMissing, int &amountOfMnFailed, int &amountOfMnStarted, std::string *aliasFilter=nullptr, std::string *error_ret=nullptr)
Definition: mnmodel.cpp:286
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: mnmodel.cpp:55
WalletModel * walletModel
Definition: mnmodel.h:84
bool addMn(CMasternodeConfig::CMasternodeEntry *entry)
Definition: mnmodel.cpp:151
bool isMNsNetworkSynced()
Definition: mnmodel.cpp:190
CMasternodeConfig::CMasternodeEntry * createLegacyMN(COutPoint &collateralOut, const std::string &alias, std::string &serviceAddr, const std::string &port, const std::string &mnKeyString, QString &ret_error)
Definition: mnmodel.cpp:318
int getMasternodeCollateralMinConf()
Definition: mnmodel.cpp:205
void resetCoinControl()
Definition: mnmodel.cpp:513
QMap< std::string, bool > collateralTxAccepted
Definition: mnmodel.h:88
CCoinControl * coinControl
Definition: mnmodel.h:85
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Definition: mnmodel.cpp:70
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition: mnmodel.cpp:62
bool removeLegacyMN(const std::string &alias_to_remove, const std::string &tx_id, unsigned int out_index, QString &ret_error)
Definition: mnmodel.cpp:417
bool isMNInactive(const QString &mnAlias)
Definition: mnmodel.cpp:171
void updateMNList()
Definition: mnmodel.cpp:30
QModelIndex index(int row, int column, const QModelIndex &parent) const override
Definition: mnmodel.cpp:125
@ PRIV_KEY
Definition: mnmodel.h:36
@ STATUS
Node status.
Definition: mnmodel.h:31
@ WAS_COLLATERAL_ACCEPTED
Definition: mnmodel.h:37
@ ALIAS
User specified MN alias.
Definition: mnmodel.h:28
@ COLLATERAL_ID
Definition: mnmodel.h:34
@ PUB_KEY
Definition: mnmodel.h:33
@ COLLATERAL_OUT_INDEX
Definition: mnmodel.h:35
@ ADDRESS
Node address.
Definition: mnmodel.h:29
void init()
Definition: mnmodel.cpp:25
void setCoinControl(CCoinControl *coinControl)
Definition: mnmodel.cpp:508
bool isMNCollateralMature(const QString &mnAlias)
Definition: mnmodel.cpp:183
int getDisplayUnit()
Definition: optionsmodel.h:74
bool IsSynced() const
int getLastBlockProcessedNum() const
void lockCoin(uint256 hash, unsigned int n, bool isTransparent=true)
void unlockCoin(uint256 hash, unsigned int n, bool isTransparent=true)
SendCoinsReturn sendCoins(WalletModelTransaction &transaction)
OptionsModel * getOptionsModel()
int getWalletTxDepth(const uint256 &txHash) const
SendCoinsReturn prepareTransaction(WalletModelTransaction *transaction, const CCoinControl *coinControl=nullptr, bool fIncludeDelegations=true)
Data model for a walletmodel transaction.
CTransactionRef & getTransaction()
std::string ToString() const
Definition: uint256.cpp:65
std::string GetHex() const
Definition: uint256.cpp:21
256-bit opaque blob.
Definition: uint256.h:138
CMasternodeConfig masternodeConfig
CMasternodeMan mnodeman
Masternode manager.
CActiveMasternode activeMasternode
Keep track of the active Masternode.
QString ProcessSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, WalletModel *walletModel, CClientUIInterface::MessageBoxFlags &informType, const QString &msgArg, bool fPrepare)
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:23
fs::ifstream ifstream
Definition: fs.h:92
bool validateMasternodeIP(const std::string &addrStr)
Definition: net.cpp:2836
CAmount nMNCollateralAmt
Definition: params.h:184
int MasternodeCollateralMinConf() const
Definition: params.h:219
fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific)
Definition: system.cpp:853
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:724
const char *const PIVX_MASTERNODE_CONF_FILENAME
Definition: system.cpp:82
fs::path GetMasternodeConfigFile()
Definition: system.cpp:776
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a Optional result.
Definition: system.h:65
TierTwoSyncState g_tiertwo_sync_state
#define strprintf
Definition: tinyformat.h:1056
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:456
uint256 uint256S(const char *str)
Definition: uint256.h:157