Skip to content

Commit

Permalink
1-click masternode
Browse files Browse the repository at this point in the history
  • Loading branch information
MasterDoge-dev committed Jul 22, 2015
1 parent e9219fb commit a1f272a
Show file tree
Hide file tree
Showing 8 changed files with 462 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ class CMainParams : public CChainParams {

vAlertPubKey = ParseHex("04bd92e9f7ec8b3c48ebb27b743ff19cc131b06b18dcac8663d75ee0cc55878057ce9989dd1c82ba13b5277c0d058dd3241ebdeefab91f38300bda1cf8fabf3ad2");

nDefaultPort = 76007;
nRPCPort = 76008;
nDefaultPort = 2589;
nRPCPort = 2588;
bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);

const char* pszTimestamp = "MasterDoge FIXED";
Expand Down
250 changes: 248 additions & 2 deletions src/chainparamsseeds.h

Large diffs are not rendered by default.

24 changes: 23 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1005,11 +1005,33 @@ bool AppInit2(boost::thread_group& threadGroup)
if (fServer)
StartRPCThreads();


BOOST_FOREACH(PAIRTYPE(std::string, CMNodeConfig) node, pwalletMain->mapMyMNodes)
{
CMNodeConfig c = node.second;
if(c.isLocal)
{
strMasterNodeAddr = c.sAddress;
strMasterNodePrivKey = c.sMasternodePrivKey;

CKey keyds;
CPubKey pubkeyds;
std::string errorMessage;
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyds, pubkeyds))
{
return InitError("Invalid masternodeprivkey. Please see documenation.");
}

activeMasternode.pubKeyMasternode = pubkeyds;
fMasterNode = true;
break;
}
}
#ifdef ENABLE_WALLET
// Mine proof-of-stake blocks in the background
if (!GetBoolArg("-staking", true))
LogPrintf("Staking disabled\n");
else if (pwalletMain)
else if (pwalletMain && !fMasterNode)
threadGroup.create_thread(boost::bind(&ThreadStakeMiner, pwalletMain));
#endif

Expand Down
14 changes: 13 additions & 1 deletion src/qt/forms/masternodemanager.ui
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
Expand Down Expand Up @@ -142,6 +142,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="localButton">
<property name="text">
<string>Create &amp;Local</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyAddressButton">
<property name="text">
Expand Down Expand Up @@ -196,6 +203,11 @@
<string>Status</string>
</property>
</column>
<column>
<property name="text">
<string>Local</string>
</property>
</column>
<column>
<property name="text">
<string>Collateral Address</string>
Expand Down
181 changes: 169 additions & 12 deletions src/qt/masternodemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "wallet.h"
#include "init.h"
#include "guiutil.h"

#include "net.h"
#include <QAbstractItemDelegate>
#include <QPainter>
#include <QTimer>
Expand Down Expand Up @@ -48,11 +48,11 @@ MasternodeManager::MasternodeManager(QWidget *parent) :
connect(timer, SIGNAL(timeout()), this, SLOT(updateNodeList()));
timer->start(30000);

LOCK(cs_pcnodes);
BOOST_FOREACH(PAIRTYPE(std::string, CMNodeConfig) node, pwalletMain->mapMyMNodes)
{
updateMNode(QString::fromStdString(node.second.sAlias), QString::fromStdString(node.second.sAddress), QString::fromStdString(node.second.sMasternodePrivKey), QString::fromStdString(node.second.sCollateralAddress));
}






updateNodeList();
}
Expand All @@ -69,12 +69,16 @@ static void NotifyMNodeUpdated(MasternodeManager *page, CMNodeConfig nodeConfig)
QString addr = QString::fromStdString(nodeConfig.sAddress);
QString privkey = QString::fromStdString(nodeConfig.sMasternodePrivKey);
QString collateral = QString::fromStdString(nodeConfig.sCollateralAddress);
QString local = "No";
if(nodeConfig.isLocal)
local = "Yes";

QMetaObject::invokeMethod(page, "updateMNode", Qt::QueuedConnection,
Q_ARG(QString, alias),
Q_ARG(QString, addr),
Q_ARG(QString, privkey),
Q_ARG(QString, collateral)
Q_ARG(QString, collateral),
Q_ARG(QString, local)
);
}

Expand Down Expand Up @@ -102,9 +106,9 @@ void MasternodeManager::on_tableWidget_2_itemSelectionChanged()
}
}

void MasternodeManager::updateMNode(QString alias, QString addr, QString privkey, QString collateral)
void MasternodeManager::updateMNode(QString alias, QString addr, QString privkey, QString collateral, QString local)
{
LOCK(cs_pcnodes);
LOCK(cs_node);
bool bFound = false;
int nodeRow = 0;
for(int i=0; i < ui->tableWidget_2->rowCount(); i++)
Expand All @@ -124,11 +128,13 @@ void MasternodeManager::updateMNode(QString alias, QString addr, QString privkey
QTableWidgetItem *addrItem = new QTableWidgetItem(addr);
QTableWidgetItem *statusItem = new QTableWidgetItem("");
QTableWidgetItem *collateralItem = new QTableWidgetItem(collateral);
QTableWidgetItem *localItem = new QTableWidgetItem(local);

ui->tableWidget_2->setItem(nodeRow, 0, aliasItem);
ui->tableWidget_2->setItem(nodeRow, 1, addrItem);
ui->tableWidget_2->setItem(nodeRow, 2, statusItem);
ui->tableWidget_2->setItem(nodeRow, 3, collateralItem);
ui->tableWidget_2->setItem(nodeRow, 3, localItem);
ui->tableWidget_2->setItem(nodeRow, 4, collateralItem);
}

static QString seconds_to_DHMS(quint32 duration)
Expand Down Expand Up @@ -185,8 +191,19 @@ void MasternodeManager::updateNodeList()
}

ui->countLabel->setText(QString::number(ui->tableWidget->rowCount()));
}

if(pwalletMain)
{
LOCK(cs_node);
BOOST_FOREACH(PAIRTYPE(std::string, CMNodeConfig) node, pwalletMain->mapMyMNodes)
{
QString local = "No";
if(node.second.isLocal)
local = "Yes";
updateMNode(QString::fromStdString(node.second.sAlias), QString::fromStdString(node.second.sAddress), QString::fromStdString(node.second.sMasternodePrivKey), QString::fromStdString(node.second.sCollateralAddress), local);
}
}
}

void MasternodeManager::setClientModel(ClientModel *model)
{
Expand Down Expand Up @@ -279,11 +296,151 @@ void MasternodeManager::on_removeButton_clicked()
ui->tableWidget_2->setRowCount(0);
BOOST_FOREACH(PAIRTYPE(std::string, CMNodeConfig) node, pwalletMain->mapMyMNodes)
{
updateMNode(QString::fromStdString(node.second.sAlias), QString::fromStdString(node.second.sAddress), QString::fromStdString(node.second.sMasternodePrivKey), QString::fromStdString(node.second.sCollateralAddress));
QString local = "No";
if(node.second.isLocal)
local = "Yes";
updateMNode(QString::fromStdString(node.second.sAlias), QString::fromStdString(node.second.sAddress), QString::fromStdString(node.second.sMasternodePrivKey), QString::fromStdString(node.second.sCollateralAddress), local);
}
}
}

void MasternodeManager::on_localButton_clicked()
{
bool bAlreadyHaveLocalTree = false;
// Check if a local masternode already exists
BOOST_FOREACH(PAIRTYPE(std::string, CMNodeConfig) node, pwalletMain->mapMyMNodes)
{
if(node.second.isLocal)
{
bAlreadyHaveLocalTree = true;
break;
}
}
if(bAlreadyHaveLocalTree)
{
QMessageBox msg;
msg.setText("A local masternode already exists.");
msg.exec();
return;
}

// Only create once the external IP is known
if(GetLocalAddress(NULL).ToStringIP() == "0.0.0.0")
{
QMessageBox msg;
msg.setText("The local external IP is not yet detected. Please try again in a few minutes.");
msg.exec();
return;
}

if(pwalletMain->GetBalance() < 20000.1*COIN)
{
QMessageBox msg;
msg.setText("You must have at least 20000.1 MDOGE to cover the 20000 MDOGE collateral for a Masternode and the tx fee.");
msg.exec();
return;
}

if (pwalletMain->IsLocked())
{
QMessageBox msg;
msg.setText("Your wallet must be unlocked so that the 20000 MDOGE collateral can be sent.");
msg.exec();
return;
}

// Automatically create an entry for the local address
CMNodeConfig c;
c.sAlias = "Local Masternode";
c.sAddress = GetLocalAddress(NULL).ToStringIPPort();
CKey secret;
secret.MakeNewKey(false);
c.sMasternodePrivKey = CBitcoinSecret(secret).ToString();

CWalletDB walletdb(pwalletMain->strWalletFile);
CAccount account;
walletdb.ReadAccount(c.sAlias, account);
bool bKeyUsed = false;
bool bForceNew = false;

// Check if the current key has been used
if (account.vchPubKey.IsValid())
{
CScript scriptPubKey;
scriptPubKey.SetDestination(account.vchPubKey.GetID());
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
++it)
{
const CWalletTx& wtx = (*it).second;
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
if (txout.scriptPubKey == scriptPubKey)
bKeyUsed = true;
}
}

// Generate a new key
if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)

{
if (!pwalletMain->GetKeyFromPool(account.vchPubKey))
{
QMessageBox msg;
msg.setText("Keypool ran out, please call keypoolrefill first.");
msg.exec();
return;
}
pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), c.sAlias);
walletdb.WriteAccount(c.sAlias, account);

}

c.sCollateralAddress = CBitcoinAddress(account.vchPubKey.GetID()).ToString();

c.isLocal = true;

pwalletMain->mapMyMNodes.insert(make_pair(c.sAddress, c));
walletdb.WriteMNodeConfig(c.sAddress, c);
uiInterface.NotifyMNodeChanged(c);

strMasterNodeAddr = c.sAddress;
strMasterNodePrivKey = c.sMasternodePrivKey;

CKey keyds;
CPubKey pubkeyds;
std::string errorMessage;
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyds, pubkeyds))
{
QMessageBox msg;
msg.setText("Invalid masternodeprivkey. Please see documenation.");
msg.exec();
return;
}

activeMasternode.pubKeyMasternode = pubkeyds;
fMasterNode = true;

CWalletTx wtx;
std::string sNarr;

string strError = pwalletMain->SendMoneyToDestination(CBitcoinAddress(account.vchPubKey.GetID()).Get(), 20000*COIN, sNarr, wtx);
if (strError != "")
{
QMessageBox msg;
msg.setText(QString::fromStdString(strError));
msg.exec();
return;
}
else
{
QMessageBox msg;
std::string sMsg = "Local Masternode created and 20000 MDOGE sent to the collateral address. Transaction hash:\n";
sMsg += wtx.GetHash().GetHex();
msg.setText(QString::fromStdString(sMsg));
msg.exec();
return;
}
}
void MasternodeManager::on_startButton_clicked()
{
// start the node
Expand Down
5 changes: 3 additions & 2 deletions src/qt/masternodemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MasternodeManager : public QWidget

public slots:
void updateNodeList();
void updateMNode(QString alias, QString addr, QString privkey, QString collateral);
void updateMNode(QString alias, QString addr, QString privkey, QString collateral, QString local);

signals:

Expand All @@ -41,7 +41,7 @@ public slots:
Ui::MasternodeManager *ui;
ClientModel *clientModel;
WalletModel *walletModel;
CCriticalSection cs_pcnodes;
CCriticalSection cs_node;
void subscribeToCoreSignals();
void unsubscribeFromCoreSignals();

Expand All @@ -50,6 +50,7 @@ private slots:
void on_createButton_clicked();
void on_editButton_clicked();
void on_getConfigButton_clicked();
void on_localButton_clicked();
void on_startButton_clicked();
void on_stopButton_clicked();
void on_startAllButton_clicked();
Expand Down
2 changes: 2 additions & 0 deletions src/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ bool
ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
CWalletScanState &wss, string& strType, string& strErr)
{

try {
// Unserialize
// Taking advantage of the fact that pair serialization
Expand Down Expand Up @@ -624,6 +625,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
return true;
}


static bool IsKeyType(string strType)
{
return (strType== "key" || strType == "wkey" ||
Expand Down
2 changes: 2 additions & 0 deletions src/walletdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class CMNodeConfig
std::string sAddress;
std::string sCollateralAddress;
std::string sMasternodePrivKey;
bool isLocal;

CMNodeConfig()
{
Expand All @@ -110,6 +111,7 @@ class CMNodeConfig
READWRITE(sAddress);
READWRITE(sCollateralAddress);
READWRITE(sMasternodePrivKey);
READWRITE(isLocal);
)
};

Expand Down

0 comments on commit a1f272a

Please sign in to comment.