mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Improve support for start-many:
- refactored CActiveMasternode - added masternodeconfig to handle remote masternode configuration - read masternodeconfig upon init - new masternode rpc commands: stop-many, start-alias, stop-alias, list-conf - added notCapableReason field for better handling not capable issues
This commit is contained in:
parent
b40755d88c
commit
2d3420c407
@ -168,6 +168,7 @@ HEADERS += src/qt/bitcoingui.h \
|
||||
src/core.h \
|
||||
src/masternode.h \
|
||||
src/activemasternode.h \
|
||||
src/masternodeconfig.h \
|
||||
src/net.h \
|
||||
src/key.h \
|
||||
src/db.h \
|
||||
@ -269,6 +270,7 @@ SOURCES += src/qt/bitcoin.cpp \
|
||||
src/instantx.cpp \
|
||||
src/masternode.cpp \
|
||||
src/activemasternode.cpp \
|
||||
src/masternodeconfig.cpp \
|
||||
src/core.cpp \
|
||||
src/init.cpp \
|
||||
src/net.cpp \
|
||||
|
@ -2,289 +2,337 @@
|
||||
#include "core.h"
|
||||
#include "activemasternode.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
CActiveMasternode activeMasternode;
|
||||
|
||||
//
|
||||
// Bootup the masternode, look for a 1000DRK input and register on the network
|
||||
//
|
||||
void CActiveMasternode::RegisterAsMasterNode(bool stop)
|
||||
void CActiveMasternode::ManageStatus()
|
||||
{
|
||||
if(!fMasterNode) return;
|
||||
std::string errorMessage;
|
||||
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Begin\n");
|
||||
|
||||
if(!fMasterNode) return;
|
||||
|
||||
//need correct adjusted time to send ping
|
||||
bool fIsInitialDownload = IsInitialBlockDownload();
|
||||
if(fIsInitialDownload) {
|
||||
isCapableMasterNode = MASTERNODE_SYNC_IN_PROCESS;
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Sync in progress. Must wait until sync is complete to start masternode.\n");
|
||||
status = MASTERNODE_SYNC_IN_PROCESS;
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Sync in progress. Must wait until sync is complete to start masternode.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string errorMessage;
|
||||
|
||||
CKey key2;
|
||||
CPubKey pubkey2;
|
||||
|
||||
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, key2, pubkey2))
|
||||
{
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Invalid masternodeprivkey: '%s'\n", errorMessage.c_str());
|
||||
exit(0);
|
||||
if(status == MASTERNODE_INPUT_TOO_NEW || status == MASTERNODE_NOT_CAPABLE || status == MASTERNODE_SYNC_IN_PROCESS){
|
||||
status = MASTERNODE_NOT_PROCESSED;
|
||||
}
|
||||
|
||||
if(isCapableMasterNode == MASTERNODE_INPUT_TOO_NEW || isCapableMasterNode == MASTERNODE_NOT_CAPABLE || isCapableMasterNode == MASTERNODE_SYNC_IN_PROCESS){
|
||||
isCapableMasterNode = MASTERNODE_NOT_PROCESSED;
|
||||
}
|
||||
|
||||
if(isCapableMasterNode == MASTERNODE_NOT_PROCESSED) {
|
||||
if(status == MASTERNODE_NOT_PROCESSED) {
|
||||
if(strMasterNodeAddr.empty()) {
|
||||
if(!GetLocal(masterNodeSignAddr)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Can't detect external address. Please use the masternodeaddr configuration option.\n");
|
||||
isCapableMasterNode = MASTERNODE_NOT_CAPABLE;
|
||||
if(!GetLocal(service)) {
|
||||
notCapableReason = "Can't detect external address. Please use the masternodeaddr configuration option.";
|
||||
status = MASTERNODE_NOT_CAPABLE;
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
masterNodeSignAddr = CService(strMasterNodeAddr);
|
||||
service = CService(strMasterNodeAddr);
|
||||
}
|
||||
|
||||
if((fTestNet && masterNodeSignAddr.GetPort() != 19999) || (!fTestNet && masterNodeSignAddr.GetPort() != 9999)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Invalid port\n");
|
||||
isCapableMasterNode = MASTERNODE_NOT_CAPABLE;
|
||||
if((fTestNet && service.GetPort() != 19999) || (!fTestNet && service.GetPort() != 9999)) {
|
||||
notCapableReason = "Invalid port: " + boost::lexical_cast<string>(service.GetPort()) + " -only 9999 or 19999 are supported.";
|
||||
status = MASTERNODE_NOT_CAPABLE;
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Checking inbound connection to '%s'\n", masterNodeSignAddr.ToString().c_str());
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString().c_str());
|
||||
|
||||
if(ConnectNode((CAddress)masterNodeSignAddr, masterNodeSignAddr.ToString().c_str())){
|
||||
masternodePortOpen = MASTERNODE_PORT_OPEN;
|
||||
} else {
|
||||
masternodePortOpen = MASTERNODE_PORT_NOT_OPEN;
|
||||
isCapableMasterNode = MASTERNODE_NOT_CAPABLE;
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Port not open.\n");
|
||||
if(!ConnectNode((CAddress)service, service.ToString().c_str())){
|
||||
notCapableReason = "Could not connect to " + service.ToString();
|
||||
status = MASTERNODE_NOT_CAPABLE;
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if(pwalletMain->IsLocked()){
|
||||
isCapableMasterNode = MASTERNODE_NOT_CAPABLE;
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Not capable.\n");
|
||||
notCapableReason = "Wallet is locked.";
|
||||
status = MASTERNODE_NOT_CAPABLE;
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
isCapableMasterNode = MASTERNODE_NOT_CAPABLE;
|
||||
// Set defaults
|
||||
status = MASTERNODE_NOT_CAPABLE;
|
||||
notCapableReason = "Unknown.";
|
||||
|
||||
CKey SecretKey;
|
||||
// Choose coins to use
|
||||
if(GetMasterNodeVin(vinMasternode, pubkeyMasterNode, SecretKey)) {
|
||||
CPubKey pubKeyCollateralAddress;
|
||||
CKey keyCollateralAddress;
|
||||
|
||||
if(GetInputAge(vinMasternode) < MASTERNODE_MIN_CONFIRMATIONS){
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Input must have least %d confirmations - %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS, GetInputAge(vinMasternode));
|
||||
isCapableMasterNode = MASTERNODE_INPUT_TOO_NEW;
|
||||
if(GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress)) {
|
||||
|
||||
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Input must have least %d confirmations - %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS, GetInputAge(vin));
|
||||
status = MASTERNODE_INPUT_TOO_NEW;
|
||||
return;
|
||||
}
|
||||
|
||||
int protocolVersion = PROTOCOL_VERSION;
|
||||
|
||||
masterNodeSignatureTime = GetAdjustedTime();
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n");
|
||||
|
||||
std::string vchPubKey(pubkeyMasterNode.begin(), pubkeyMasterNode.end());
|
||||
std::string vchPubKey2(pubkey2.begin(), pubkey2.end());
|
||||
std::string strMessage = masterNodeSignAddr.ToString() + boost::lexical_cast<std::string>(masterNodeSignatureTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion);
|
||||
status = MASTERNODE_IS_CAPABLE;
|
||||
notCapableReason = "";
|
||||
|
||||
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, SecretKey)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Sign message failed\n");
|
||||
return;
|
||||
}
|
||||
pwalletMain->LockCoin(vin.prevout);
|
||||
|
||||
if(!darkSendSigner.VerifyMessage(pubkeyMasterNode, vchMasterNodeSignature, strMessage, errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Verify message failed\n");
|
||||
return;
|
||||
}
|
||||
// send to all nodes
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Is capable master node!\n");
|
||||
|
||||
isCapableMasterNode = MASTERNODE_IS_CAPABLE;
|
||||
|
||||
pwalletMain->LockCoin(vinMasternode.prevout);
|
||||
|
||||
bool found = false;
|
||||
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes)
|
||||
if(mn.vin == vinMasternode)
|
||||
found = true;
|
||||
|
||||
if(!found) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Adding myself to masternode list %s - %s\n", masterNodeSignAddr.ToString().c_str(), vinMasternode.ToString().c_str());
|
||||
CMasterNode mn(masterNodeSignAddr, vinMasternode, pubkeyMasterNode, vchMasterNodeSignature, masterNodeSignatureTime, pubkey2, PROTOCOL_VERSION);
|
||||
mn.UpdateLastSeen(masterNodeSignatureTime);
|
||||
darkSendMasterNodes.push_back(mn);
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Masternode input = %s\n", vinMasternode.ToString().c_str());
|
||||
}
|
||||
|
||||
//relay to all
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode))
|
||||
{
|
||||
pnode->PushMessage("dsee", vinMasternode, masterNodeSignAddr, vchMasterNodeSignature, masterNodeSignatureTime, pubkeyMasterNode, pubkey2, -1, -1, masterNodeSignatureTime, protocolVersion);
|
||||
LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Error on Register: %s", errorMessage.c_str());
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Could not find suitable coins!\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(isCapableMasterNode != MASTERNODE_IS_CAPABLE && isCapableMasterNode != MASTERNODE_REMOTELY_ENABLED) return;
|
||||
//send to all peers
|
||||
if(!Dseep(errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s", errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
masterNodeSignatureTime = GetAdjustedTime();
|
||||
// Send stop dseep to network for remote masternode
|
||||
bool CActiveMasternode::StopMasterNode(std::string strService, std::string strKeyMasternode, std::string& errorMessage) {
|
||||
CTxIn vin;
|
||||
CKey keyMasternode;
|
||||
CPubKey pubKeyMasternode;
|
||||
|
||||
std::string strMessage = masterNodeSignAddr.ToString() + boost::lexical_cast<std::string>(masterNodeSignatureTime) + boost::lexical_cast<std::string>(stop);
|
||||
if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) {
|
||||
LogPrintf("CActiveMasternode::StopMasterNode() - Error: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, key2)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Sign message failed\n");
|
||||
return;
|
||||
return StopMasterNode(vin, CService(strService), keyMasternode, pubKeyMasternode, errorMessage);
|
||||
}
|
||||
|
||||
// Send stop dseep to network for main masternode
|
||||
bool CActiveMasternode::StopMasterNode(std::string& errorMessage) {
|
||||
if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) {
|
||||
errorMessage = "masternode is not in a running status";
|
||||
LogPrintf("CActiveMasternode::StopMasterNode() - Error: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
status = MASTERNODE_STOPPED;
|
||||
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
|
||||
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode))
|
||||
{
|
||||
LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!darkSendSigner.VerifyMessage(pubkey2, vchMasterNodeSignature, strMessage, errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Verify message failed\n");
|
||||
return;
|
||||
return StopMasterNode(vin, service, keyMasternode, pubKeyMasternode, errorMessage);
|
||||
}
|
||||
|
||||
// Send stop dseep to network for any masternode
|
||||
bool CActiveMasternode::StopMasterNode(CTxIn vin, CService service, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage) {
|
||||
pwalletMain->UnlockCoin(vin.prevout);
|
||||
return Dseep(vin, service, keyMasternode, pubKeyMasternode, errorMessage, true);
|
||||
}
|
||||
|
||||
bool CActiveMasternode::Dseep(std::string& errorMessage) {
|
||||
if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) {
|
||||
errorMessage = "masternode is not in a running status";
|
||||
LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
|
||||
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode))
|
||||
{
|
||||
LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return Dseep(vin, service, keyMasternode, pubKeyMasternode, errorMessage, false);
|
||||
}
|
||||
|
||||
bool CActiveMasternode::Dseep(CTxIn vin, CService service, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage, bool stop) {
|
||||
std::string errorMessage;
|
||||
std::vector<unsigned char> vchMasterNodeSignature;
|
||||
std::string strMasterNodeSignMessage;
|
||||
int64 masterNodeSignatureTime = GetAdjustedTime();
|
||||
|
||||
std::string strMessage = service.ToString() + boost::lexical_cast<std::string>(masterNodeSignatureTime) + boost::lexical_cast<std::string>(stop);
|
||||
|
||||
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyMasternode)) {
|
||||
retErrorMessage = "sign message failed: " + errorMessage;
|
||||
LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", retErrorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchMasterNodeSignature, strMessage, errorMessage)) {
|
||||
retErrorMessage = "Verify message failed: " + errorMessage;
|
||||
LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", retErrorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update Last Seen timestamp in masternode list
|
||||
bool found = false;
|
||||
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes) {
|
||||
//LogPrintf(" -- %s\n", mn.vin.ToString().c_str());
|
||||
|
||||
if(mn.vin == vinMasternode) {
|
||||
if(mn.vin == vin) {
|
||||
found = true;
|
||||
mn.UpdateLastSeen();
|
||||
}
|
||||
}
|
||||
|
||||
if(!found){
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Darksend Masternode List doesn't include our masternode, Shutting down masternode pinging service! %s\n", vinMasternode.ToString().c_str());
|
||||
isCapableMasterNode = MASTERNODE_STOPPED;
|
||||
return;
|
||||
// Seems like we are trying to send a ping while the masternode is not registered in the network
|
||||
retErrorMessage = "Darksend Masternode List doesn't include our masternode, Shutting down masternode pinging service! " + vin.ToString();
|
||||
LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", retErrorMessage.c_str());
|
||||
status = MASTERNODE_NOT_CAPABLE;
|
||||
notCapableReason = retErrorMessage;
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Masternode input = %s\n", vinMasternode.ToString().c_str());
|
||||
//send to all peers
|
||||
LogPrintf("CActiveMasternode::Dseep() - SendDarkSendElectionEntryPing vin = %s\n", vin.ToString().c_str());
|
||||
SendDarkSendElectionEntryPing(vin, vchMasterNodeSignature, masterNodeSignatureTime, stop);
|
||||
|
||||
if (stop) isCapableMasterNode = MASTERNODE_STOPPED;
|
||||
|
||||
//relay to all peers
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
pnode->PushMessage("dseep", vinMasternode, vchMasterNodeSignature, masterNodeSignatureTime, stop);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Bootup the masternode, look for a 1000DRK input and register on the network
|
||||
// Takes 2 parameters to start a remote masternode
|
||||
//
|
||||
bool CActiveMasternode::RegisterAsMasterNodeRemoteOnly(std::string strMasterNodeAddr, std::string strMasterNodePrivKey)
|
||||
{
|
||||
if(!fMasterNode) return false;
|
||||
bool CActiveMasternode::Register(std::string strService, std::string strKeyMasternode, std::string txHash, std::string strOutputIndex, std::string& errorMessage) {
|
||||
CTxIn vin;
|
||||
CPubKey pubKeyCollateralAddress;
|
||||
CKey keyCollateralAddress;
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Address %s MasterNodePrivKey %s\n", strMasterNodeAddr.c_str(), strMasterNodePrivKey.c_str());
|
||||
if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode))
|
||||
{
|
||||
LogPrintf("Register::Register() - Error upon calling SetKey: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress, txHash, strOutputIndex)) {
|
||||
errorMessage = "could not allocate vin";
|
||||
LogPrintf("Register::Register() - Error: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
return Register(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage);
|
||||
}
|
||||
|
||||
bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage) {
|
||||
std::string errorMessage;
|
||||
std::vector<unsigned char> vchMasterNodeSignature;
|
||||
std::string strMasterNodeSignMessage;
|
||||
int64 masterNodeSignatureTime = GetAdjustedTime();
|
||||
|
||||
CKey key2;
|
||||
CPubKey pubkey2;
|
||||
std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
|
||||
std::string vchPubKey2(pubKeyMasternode.begin(), pubKeyMasternode.end());
|
||||
|
||||
std::string strMessage = service.ToString() + boost::lexical_cast<std::string>(masterNodeSignatureTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(PROTOCOL_VERSION);
|
||||
|
||||
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, key2, pubkey2))
|
||||
{
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Invalid masternodeprivkey: '%s'\n", errorMessage.c_str());
|
||||
return false;
|
||||
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyCollateralAddress)) {
|
||||
retErrorMessage = "sign message failed: " + errorMessage;
|
||||
LogPrintf("CActiveMasternode::Register() - Error: %s\n", retErrorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
CService masterNodeSignAddr = CService(strMasterNodeAddr);
|
||||
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes){
|
||||
if(mn.addr == masterNodeSignAddr){
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Address in use\n");
|
||||
return false;
|
||||
}
|
||||
if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchMasterNodeSignature, strMessage, errorMessage)) {
|
||||
retErrorMessage = "Verify message failed: " + errorMessage;
|
||||
LogPrintf("CActiveMasternode::Register() - Error: %s\n", retErrorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes)
|
||||
if(mn.vin == vin)
|
||||
found = true;
|
||||
|
||||
if(!found) {
|
||||
LogPrintf("CActiveMasternode::Register() - Adding to masternode list service: %s - vin: %s\n", service.ToString().c_str(), vin.ToString().c_str());
|
||||
CMasterNode mn(service, vin, pubKeyCollateralAddress, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyMasternode, PROTOCOL_VERSION);
|
||||
mn.UpdateLastSeen(masterNodeSignatureTime);
|
||||
darkSendMasterNodes.push_back(mn);
|
||||
}
|
||||
|
||||
if((fTestNet && masterNodeSignAddr.GetPort() != 19999) || (!fTestNet && masterNodeSignAddr.GetPort() != 9999)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Invalid port\n");
|
||||
return false;
|
||||
}
|
||||
//send to all peers
|
||||
LogPrintf("CActiveMasternode::Register() - SendDarkSendElectionEntry vin = %s\n", vin.ToString().c_str());
|
||||
SendDarkSendElectionEntry(vin, service, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyCollateralAddress, pubKeyMasternode, -1, -1, masterNodeSignatureTime, PROTOCOL_VERSION);
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Checking inbound connection to '%s'\n", masterNodeSignAddr.ToString().c_str());
|
||||
|
||||
if(!ConnectNode((CAddress)masterNodeSignAddr, masterNodeSignAddr.ToString().c_str())){
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Error connecting to port\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(pwalletMain->IsLocked()){
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Wallet is locked\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CKey SecretKey;
|
||||
CTxIn vinMasternode;
|
||||
CPubKey pubkeyMasterNode;
|
||||
int masterNodeSignatureTime = 0;
|
||||
|
||||
// Choose coins to use
|
||||
while (GetMasterNodeVin(vinMasternode, pubkeyMasterNode, SecretKey)) {
|
||||
// don't use a vin that's registered
|
||||
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes)
|
||||
if(mn.vin == vinMasternode)
|
||||
continue;
|
||||
|
||||
if(GetInputAge(vinMasternode) < MASTERNODE_MIN_CONFIRMATIONS)
|
||||
continue;
|
||||
|
||||
masterNodeSignatureTime = GetAdjustedTime();
|
||||
|
||||
std::string vchPubKey(pubkeyMasterNode.begin(), pubkeyMasterNode.end());
|
||||
std::string vchPubKey2(pubkey2.begin(), pubkey2.end());
|
||||
std::string strMessage = masterNodeSignAddr.ToString() + boost::lexical_cast<std::string>(masterNodeSignatureTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(PROTOCOL_VERSION);
|
||||
|
||||
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, SecretKey)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Sign message failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!darkSendSigner.VerifyMessage(pubkeyMasterNode, vchMasterNodeSignature, strMessage, errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Verify message failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Is capable master node!\n");
|
||||
|
||||
pwalletMain->LockCoin(vinMasternode.prevout);
|
||||
|
||||
int protocolVersion = PROTOCOL_VERSION;
|
||||
//relay to all
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
pnode->PushMessage("dsee", vinMasternode, masterNodeSignAddr, vchMasterNodeSignature, masterNodeSignatureTime, pubkeyMasterNode, pubkey2, -1, -1, masterNodeSignatureTime, protocolVersion);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - No sutable vin found\n");
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey) {
|
||||
return GetMasterNodeVin(vin, pubkey, secretKey, "", "");
|
||||
}
|
||||
|
||||
bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey)
|
||||
{
|
||||
int64 nValueIn = 0;
|
||||
bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex) {
|
||||
CScript pubScript;
|
||||
|
||||
// try once before we try to denominate
|
||||
if (!pwalletMain->SelectCoinsMasternode(vin, nValueIn, pubScript))
|
||||
{
|
||||
if(fDebug) LogPrintf("CActiveMasternode::GetMasterNodeVin - I'm not a capable masternode\n");
|
||||
return false;
|
||||
// Find possible candidates
|
||||
vector<COutput> possibleCoins = SelectCoinsMasternode();
|
||||
COutput *selectedOutput;
|
||||
|
||||
// Find the vin
|
||||
if(!strTxHash.empty()) {
|
||||
// Let's find it
|
||||
uint256 txHash(strTxHash);
|
||||
int outputIndex = boost::lexical_cast<int>(outputIndex);
|
||||
bool found = false;
|
||||
BOOST_FOREACH(COutput& out, possibleCoins) {
|
||||
if(true) {
|
||||
selectedOutput = &out;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
LogPrintf("CActiveMasternode::GetMasterNodeVin - Could not locate valid vin\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// No output specified, Select the first one
|
||||
if(possibleCoins.size() > 0) {
|
||||
selectedOutput = &possibleCoins[0];
|
||||
} else {
|
||||
LogPrintf("CActiveMasternode::GetMasterNodeVin - Could not locate specified vin from possible list\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CTxDestination address1;
|
||||
// At this point we have a selected output, retrieve the associated info
|
||||
return GetVinFromOutput(*selectedOutput, vin, pubkey, secretKey);
|
||||
}
|
||||
|
||||
|
||||
// Extract masternode vin information from output
|
||||
bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey) {
|
||||
|
||||
CScript pubScript;
|
||||
|
||||
vin = CTxIn(out.tx->GetHash(),out.i);
|
||||
pubScript = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey
|
||||
|
||||
CTxDestination address1;
|
||||
ExtractDestination(pubScript, address1);
|
||||
CBitcoinAddress address2(address1);
|
||||
|
||||
@ -303,16 +351,62 @@ bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secr
|
||||
return true;
|
||||
}
|
||||
|
||||
// get all possible outputs for running masternode
|
||||
vector<COutput> CActiveMasternode::SelectCoinsMasternode()
|
||||
{
|
||||
CCoinControl *coinControl=NULL;
|
||||
vector<COutput> vCoins;
|
||||
vector<COutput> filteredCoins;
|
||||
|
||||
// Retrieve all possible outputs
|
||||
pwalletMain->AvailableCoins(vCoins, true, coinControl, ALL_COINS);
|
||||
|
||||
// Filter
|
||||
BOOST_FOREACH(const COutput& out, vCoins)
|
||||
{
|
||||
if(out.tx->vout[out.i].nValue == 1000*COIN) { //exactly
|
||||
filteredCoins.push_back(out);
|
||||
}
|
||||
}
|
||||
return filteredCoins;
|
||||
}
|
||||
|
||||
|
||||
/* select coins with specified transaction hash and output index */
|
||||
/*
|
||||
bool CActiveMasternode::SelectCoinsMasternode(CTxIn& vin, int64& nValueIn, CScript& pubScript, std::string strTxHash, std::string strOutputIndex)
|
||||
{
|
||||
CWalletTx ctx;
|
||||
|
||||
// Convert configuration strings
|
||||
uint256 txHash;
|
||||
int outputIndex;
|
||||
txHash.SetHex(strTxHash);
|
||||
std::istringstream(strOutputIndex) >> outputIndex;
|
||||
|
||||
if(pwalletMain->GetTransaction(txHash, ctx)) {
|
||||
if(ctx.vout[outputIndex].nValue == 1000*COIN) { //exactly
|
||||
vin = CTxIn(ctx.GetHash(), outputIndex);
|
||||
pubScript = ctx.vout[outputIndex].scriptPubKey; // the inputs PubKey
|
||||
nValueIn = ctx.vout[outputIndex].nValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
// when starting a masternode, this can enable to run as a hot wallet with no funds
|
||||
bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& vin, int64 sigTime, CService& addr)
|
||||
bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& newVin, CService& newService)
|
||||
{
|
||||
if(!fMasterNode) return false;
|
||||
|
||||
isCapableMasterNode = MASTERNODE_REMOTELY_ENABLED;
|
||||
status = MASTERNODE_REMOTELY_ENABLED;
|
||||
|
||||
vinMasternode = vin;
|
||||
masterNodeSignatureTime = sigTime;
|
||||
masterNodeSignAddr = addr;
|
||||
//The values below are needed for signing dseep messages going forward
|
||||
this->vin = newVin;
|
||||
this->service = newService;
|
||||
|
||||
LogPrintf("CActiveMasternode::EnableHotColdMasterNode() - Enabled! You may shut down the cold daemon.\n");
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
@ -21,36 +20,45 @@ extern CActiveMasternode activeMasternode;
|
||||
class CActiveMasternode
|
||||
{
|
||||
public:
|
||||
CTxIn vinMasternode;
|
||||
CPubKey pubkeyMasterNode;
|
||||
CPubKey pubkeyMasterNode2;
|
||||
// Initialized by init.cpp
|
||||
// Keys for the main masternode
|
||||
CPubKey pubKeyMasternode;
|
||||
|
||||
std::string strMasterNodeSignMessage;
|
||||
std::vector<unsigned char> vchMasterNodeSignature;
|
||||
// Initialized while registering masternode
|
||||
CTxIn vin;
|
||||
CService service;
|
||||
|
||||
std::string masterNodeAddr;
|
||||
CService masterNodeSignAddr;
|
||||
|
||||
int isCapableMasterNode;
|
||||
int64 masterNodeSignatureTime;
|
||||
int masternodePortOpen;
|
||||
int status;
|
||||
std::string notCapableReason;
|
||||
|
||||
CActiveMasternode()
|
||||
{
|
||||
isCapableMasterNode = MASTERNODE_NOT_PROCESSED;
|
||||
masternodePortOpen = 0;
|
||||
status = MASTERNODE_NOT_PROCESSED;
|
||||
}
|
||||
|
||||
void ManageStatus(); // manage status of main masternode
|
||||
|
||||
bool Dseep(std::string& errorMessage); // ping for main masternode
|
||||
bool Dseep(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string &retErrorMessage, bool stop); // ping for any masternode
|
||||
|
||||
bool StopMasterNode(std::string& errorMessage); // stop main masternode
|
||||
bool StopMasterNode(std::string strService, std::string strKeyMasternode, std::string& errorMessage); // stop remote masternode
|
||||
bool StopMasterNode(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string& errorMessage); // stop any masternode
|
||||
|
||||
bool Register(std::string strService, std::string strKey, std::string txHash, std::string strOutputIndex, std::string& errorMessage); // register remote masternode
|
||||
bool Register(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage); // register any masternode
|
||||
|
||||
// get 1000DRK input that can be used for the masternode
|
||||
bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey);
|
||||
bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex);
|
||||
vector<COutput> SelectCoinsMasternode();
|
||||
bool GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey);
|
||||
|
||||
// start the masternode and register with the network
|
||||
void RegisterAsMasterNode(bool stop);
|
||||
// start a remote masternode
|
||||
bool RegisterAsMasterNodeRemoteOnly(std::string strMasterNodeAddr, std::string strMasterNodePrivKey);
|
||||
//bool SelectCoinsMasternode(CTxIn& vin, int64& nValueIn, CScript& pubScript, std::string strTxHash, std::string strOutputIndex);
|
||||
|
||||
// enable hot wallet mode (run a masternode with no funds)
|
||||
bool EnableHotColdMasterNode(CTxIn& vin, int64 sigTime, CService& addr);
|
||||
bool EnableHotColdMasterNode(CTxIn& vin, CService& addr);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -109,7 +109,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
|
||||
vRecv >> nDenom >> txCollateral;
|
||||
|
||||
std::string error = "";
|
||||
int mn = GetMasternodeByVin(activeMasternode.vinMasternode);
|
||||
int mn = GetMasternodeByVin(activeMasternode.vin);
|
||||
if(mn == -1){
|
||||
std::string strError = "Not in the masternode list";
|
||||
pfrom->PushMessage("dssu", darkSendPool.sessionID, darkSendPool.GetState(), darkSendPool.GetEntriesCount(), MASTERNODE_REJECTED, strError);
|
||||
@ -591,7 +591,7 @@ void CDarkSendPool::Check()
|
||||
if(!mapDarksendBroadcastTxes.count(txNew.GetHash())){
|
||||
CDarksendBroadcastTx dstx;
|
||||
dstx.tx = txNew;
|
||||
dstx.vin = activeMasternode.vinMasternode;
|
||||
dstx.vin = activeMasternode.vin;
|
||||
dstx.vchSig = vchSig;
|
||||
dstx.sigTime = sigTime;
|
||||
|
||||
@ -799,7 +799,7 @@ void CDarkSendPool::CheckTimeout(){
|
||||
if(state == POOL_STATUS_QUEUE && sessionUsers == GetMaxPoolTransactions()) {
|
||||
CDarksendQueue dsq;
|
||||
dsq.nDenom = sessionDenom;
|
||||
dsq.vin = activeMasternode.vinMasternode;
|
||||
dsq.vin = activeMasternode.vin;
|
||||
dsq.time = GetTime();
|
||||
dsq.ready = true;
|
||||
dsq.Sign();
|
||||
@ -1852,7 +1852,7 @@ bool CDarkSendPool::IsCompatibleWithSession(int64 nDenom, CTransaction txCollate
|
||||
//broadcast that I'm accepting entries, only if it's the first entry though
|
||||
CDarksendQueue dsq;
|
||||
dsq.nDenom = nDenom;
|
||||
dsq.vin = activeMasternode.vinMasternode;
|
||||
dsq.vin = activeMasternode.vin;
|
||||
dsq.time = GetTime();
|
||||
dsq.Sign();
|
||||
dsq.Relay();
|
||||
@ -2104,6 +2104,8 @@ void ThreadCheckDarkSendPool()
|
||||
RenameThread("bitcoin-darksend");
|
||||
|
||||
unsigned int c = 0;
|
||||
std::string errorMessage;
|
||||
|
||||
while (true)
|
||||
{
|
||||
c++;
|
||||
@ -2152,16 +2154,14 @@ void ThreadCheckDarkSendPool()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(c % MASTERNODE_PING_SECONDS == 0){
|
||||
activeMasternode.RegisterAsMasterNode(false);
|
||||
activeMasternode.ManageStatus();
|
||||
}
|
||||
|
||||
if(c % 60 == 0){
|
||||
//if we've used 1/5 of the masternode list, then clear the list.
|
||||
if((int)vecMasternodesUsed.size() > (int)darkSendMasterNodes.size() / 5)
|
||||
vecMasternodesUsed.clear();
|
||||
|
||||
}
|
||||
|
||||
//auto denom every 2.5 minutes (liquidity provides try less often)
|
||||
|
10
src/init.cpp
10
src/init.cpp
@ -12,6 +12,7 @@
|
||||
#include "ui_interface.h"
|
||||
#include "checkpointsync.h"
|
||||
#include "activemasternode.h"
|
||||
#include "masternodeconfig.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
@ -198,6 +199,10 @@ bool AppInit(int argc, char* argv[])
|
||||
return false;
|
||||
}
|
||||
|
||||
// Process masternode config
|
||||
masternodeConfig.read(GetMasternodeConfigFile());
|
||||
|
||||
|
||||
// Command-line RPC
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "darkcoin:"))
|
||||
@ -384,7 +389,8 @@ std::string HelpMessage()
|
||||
|
||||
"\n" + _("Masternode options:") + "\n" +
|
||||
" -masternode=<n> " + _("Enable the client to act as a masternode (0-1, default: 0)") + "\n" +
|
||||
" -masternodeprivkey=<n> " + _("Set the masternode private key") + "\n" +
|
||||
" -mnconf=<file> " + _("Specify masternode configuration file (default: masternode.conf)") + "\n" +
|
||||
" -masternodeprivkey=<n> " + _("Set the masternode private key") + "\n" +
|
||||
" -masternodeaddr=<n> " + _("Set external address:port to get to this masternode (example: address:port)") + "\n" +
|
||||
" -masternodeminprotocol=<n> " + _("Ignore masternodes less than version (example: 70050; default : 0)") + "\n" +
|
||||
|
||||
@ -1232,7 +1238,7 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
return InitError(_("Invalid masternodeprivkey. Please see documenation."));
|
||||
}
|
||||
|
||||
activeMasternode.pubkeyMasterNode2 = pubkey;
|
||||
activeMasternode.pubKeyMasternode = pubkey;
|
||||
|
||||
} else {
|
||||
return InitError(_("You must specify a masternodeprivkey in the configuration. Please see documentation for help."));
|
||||
|
@ -207,7 +207,7 @@ void DoConsensusVote(CTransaction& tx, bool approved, int64 nBlockHeight)
|
||||
}
|
||||
|
||||
int winner = GetCurrentMasterNode(1, nBlockHeight);
|
||||
int n = GetMasternodeRank(activeMasternode.vinMasternode, nBlockHeight, MIN_INSTANTX_PROTO_VERSION);
|
||||
int n = GetMasternodeRank(activeMasternode.vin, nBlockHeight, MIN_INSTANTX_PROTO_VERSION);
|
||||
|
||||
if(n == -1 || winner == -1)
|
||||
{
|
||||
@ -225,7 +225,7 @@ void DoConsensusVote(CTransaction& tx, bool approved, int64 nBlockHeight)
|
||||
}
|
||||
|
||||
CConsensusVote ctx;
|
||||
ctx.vinMasternode = activeMasternode.vinMasternode;
|
||||
ctx.vinMasternode = activeMasternode.vin;
|
||||
ctx.approved = approved;
|
||||
ctx.txHash = tx.GetHash();
|
||||
ctx.nBlockHeight = nBlockHeight;
|
||||
@ -274,7 +274,7 @@ void ProcessConsensusVote(CConsensusVote& ctx)
|
||||
}
|
||||
|
||||
//We're not the winning masternode
|
||||
if(darkSendMasterNodes[winner].vin != activeMasternode.vinMasternode) {
|
||||
if(darkSendMasterNodes[winner].vin != activeMasternode.vin) {
|
||||
LogPrintf("InstantX::ProcessConsensusVote - I'm not the winning masternode\n");
|
||||
return;
|
||||
}
|
||||
@ -453,4 +453,4 @@ void CTransactionLock::AddSignature(CConsensusVote cv)
|
||||
int CTransactionLock::CountSignatures()
|
||||
{
|
||||
return vecConsensusVotes.size();
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ OBJS= \
|
||||
obj/core.o \
|
||||
obj/masternode.o \
|
||||
obj/activemasternode.o \
|
||||
obj/masternodeconfig.o \
|
||||
obj/instantx.o \
|
||||
obj/keystore.o \
|
||||
obj/darksend.o \
|
||||
|
@ -85,6 +85,7 @@ OBJS= \
|
||||
obj/core.o \
|
||||
obj/masternode.o \
|
||||
obj/activemasternode.o \
|
||||
obj/masternodeconfig.o \
|
||||
obj/instantx.o \
|
||||
obj/keystore.o \
|
||||
obj/main.o \
|
||||
|
@ -90,6 +90,7 @@ OBJS= \
|
||||
obj/core.o \
|
||||
obj/masternode.o \
|
||||
obj/activemasternode.o \
|
||||
obj/masternodeconfig.o \
|
||||
obj/instantx.o \
|
||||
obj/keystore.o \
|
||||
obj/main.o \
|
||||
|
@ -127,6 +127,7 @@ OBJS= \
|
||||
obj/init.o \
|
||||
obj/core.o \
|
||||
obj/masternode.o \
|
||||
obj/masternodeconfig.o \
|
||||
obj/activemasternode.o \
|
||||
obj/instantx.o \
|
||||
obj/keystore.o \
|
||||
|
@ -1,11 +1,8 @@
|
||||
|
||||
|
||||
#include "masternode.h"
|
||||
#include "activemasternode.h"
|
||||
#include "darksend.h"
|
||||
#include "core.h"
|
||||
|
||||
|
||||
/** The list of active masternodes */
|
||||
std::vector<CMasterNode> darkSendMasterNodes;
|
||||
/** Object for who's going to get paid on which blocks */
|
||||
@ -163,8 +160,8 @@ void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream
|
||||
darkSendMasterNodes.push_back(mn);
|
||||
|
||||
// if it matches our masternodeprivkey, then we've been remotely activated
|
||||
if(pubkey2 == activeMasternode.pubkeyMasterNode2 && protocolVersion == PROTOCOL_VERSION){
|
||||
activeMasternode.EnableHotColdMasterNode(vin, sigTime, addr);
|
||||
if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){
|
||||
activeMasternode.EnableHotColdMasterNode(vin, addr);
|
||||
}
|
||||
|
||||
if(count == -1 && !isLocal)
|
||||
@ -194,6 +191,8 @@ void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream
|
||||
bool stop;
|
||||
vRecv >> vin >> vchSig >> sigTime >> stop;
|
||||
|
||||
//LogPrintf("dseep - Received: vin: %s sigTime: %lld stop: %s\n", vin.ToString().c_str(), sigTime, stop ? "true" : "false");
|
||||
|
||||
if (sigTime > GetAdjustedTime() + 60 * 60) {
|
||||
LogPrintf("dseep - Signature rejected, too far into the future %s\n", vin.ToString().c_str());
|
||||
return;
|
||||
@ -208,7 +207,8 @@ void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream
|
||||
|
||||
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes) {
|
||||
if(mn.vin.prevout == vin.prevout) {
|
||||
// take this only if it's newer
|
||||
// LogPrintf("dseep - Found corresponding mn for vin: %s\n", vin.ToString().c_str());
|
||||
// take this only if it's newer
|
||||
if(mn.lastDseep < sigTime){
|
||||
std::string strMessage = mn.addr.ToString() + boost::lexical_cast<std::string>(sigTime) + boost::lexical_cast<std::string>(stop);
|
||||
|
||||
|
31
src/masternodeconfig.cpp
Normal file
31
src/masternodeconfig.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "masternodeconfig.h"
|
||||
#include "util.h"
|
||||
|
||||
CMasternodeConfig masternodeConfig;
|
||||
|
||||
void CMasternodeConfig::add(std::string alias, std::string ip, std::string privKey, std::string txHash, std::string outputIndex) {
|
||||
CMasternodeEntry cme(alias, ip, privKey, txHash, outputIndex);
|
||||
entries.push_back(cme);
|
||||
}
|
||||
|
||||
void CMasternodeConfig::read(boost::filesystem::path path) {
|
||||
boost::filesystem::ifstream streamConfig(GetMasternodeConfigFile());
|
||||
if (!streamConfig.good()) {
|
||||
return; // No masternode.conf file is OK
|
||||
}
|
||||
|
||||
for(std::string line; std::getline(streamConfig, line); )
|
||||
{
|
||||
if(line.empty()) {
|
||||
continue;
|
||||
}
|
||||
std::istringstream iss(line);
|
||||
std::string alias, ip, privKey, txHash, outputIndex;
|
||||
if (!(iss >> alias >> ip >> privKey >> txHash >> outputIndex)) {
|
||||
LogPrintf("CMasternodeConfig::read - Could not parse masternode.conf. Line: %s\n", line.c_str());
|
||||
}
|
||||
add(alias, ip, privKey, txHash, outputIndex);
|
||||
}
|
||||
|
||||
streamConfig.close();
|
||||
}
|
102
src/masternodeconfig.h
Normal file
102
src/masternodeconfig.h
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef SRC_MASTERNODECONFIG_H_
|
||||
#define SRC_MASTERNODECONFIG_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
class CMasternodeConfig;
|
||||
extern CMasternodeConfig masternodeConfig;
|
||||
|
||||
class CMasternodeConfig
|
||||
{
|
||||
|
||||
public:
|
||||
class CMasternodeEntry {
|
||||
|
||||
private:
|
||||
std::string alias;
|
||||
std::string ip;
|
||||
std::string privKey;
|
||||
std::string txHash;
|
||||
std::string outputIndex;
|
||||
|
||||
public:
|
||||
|
||||
CMasternodeEntry(std::string alias, std::string ip, std::string privKey, std::string txHash, std::string outputIndex) {
|
||||
this->alias = alias;
|
||||
this->ip = ip;
|
||||
this->privKey = privKey;
|
||||
this->txHash = txHash;
|
||||
this->outputIndex = outputIndex;
|
||||
}
|
||||
|
||||
const std::string& getAlias() const {
|
||||
return alias;
|
||||
}
|
||||
|
||||
void setAlias(const std::string& alias) {
|
||||
this->alias = alias;
|
||||
}
|
||||
|
||||
const std::string& getOutputIndex() const {
|
||||
return outputIndex;
|
||||
}
|
||||
|
||||
void setOutputIndex(const std::string& outputIndex) {
|
||||
this->outputIndex = outputIndex;
|
||||
}
|
||||
|
||||
const std::string& getPrivKey() const {
|
||||
return privKey;
|
||||
}
|
||||
|
||||
void setPrivKey(const std::string& privKey) {
|
||||
this->privKey = privKey;
|
||||
}
|
||||
|
||||
const std::string& getTxHash() const {
|
||||
return txHash;
|
||||
}
|
||||
|
||||
void setTxHash(const std::string& txHash) {
|
||||
this->txHash = txHash;
|
||||
}
|
||||
|
||||
const std::string& getIp() const {
|
||||
return ip;
|
||||
}
|
||||
|
||||
void setIp(const std::string& ip) {
|
||||
this->ip = ip;
|
||||
}
|
||||
};
|
||||
|
||||
CMasternodeConfig() {
|
||||
entries = std::vector<CMasternodeEntry>();
|
||||
}
|
||||
|
||||
void clear();
|
||||
void read(boost::filesystem::path path);
|
||||
void add(std::string alias, std::string ip, std::string privKey, std::string txHash, std::string outputIndex);
|
||||
|
||||
std::vector<CMasternodeEntry>& getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<CMasternodeEntry> entries;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* SRC_MASTERNODECONFIG_H_ */
|
||||
|
20
src/net.cpp
20
src/net.cpp
@ -1970,6 +1970,15 @@ void RelayDarkSendElectionEntry(const CTxIn vin, const CService addr, const std:
|
||||
}
|
||||
}
|
||||
|
||||
void SendDarkSendElectionEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64 nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64 lastUpdated, const int protocolVersion)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
pnode->PushMessage("dsee", vin, addr, vchSig, nNow, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void RelayDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64 nNow, const bool stop)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
@ -1981,6 +1990,15 @@ void RelayDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned
|
||||
}
|
||||
}
|
||||
|
||||
void SendDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64 nNow, const bool stop)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
pnode->PushMessage("dseep", vin, vchSig, nNow, stop);
|
||||
}
|
||||
}
|
||||
|
||||
void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
@ -1988,4 +2006,4 @@ void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, co
|
||||
{
|
||||
pnode->PushMessage("dsc", sessionID, error, errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -691,7 +691,9 @@ void RelayDarkSendFinalTransaction(const int sessionID, const CTransaction& txNe
|
||||
void RelayDarkSendIn(const std::vector<CTxIn>& in, const int64& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& out);
|
||||
void RelayDarkSendStatus(const int sessionID, const int newState, const int newEntriesCount, const int newAccepted, const std::string error="");
|
||||
void RelayDarkSendElectionEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64 nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64 lastUpdated, const int protocolVersion);
|
||||
void SendDarkSendElectionEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64 nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64 lastUpdated, const int protocolVersion);
|
||||
void RelayDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64 nNow, const bool stop);
|
||||
void SendDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64 nNow, const bool stop);
|
||||
void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage);
|
||||
void RelayDarkSendMasterNodeContestant();
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "ui_interface.h"
|
||||
#include "paymentserver.h"
|
||||
#include "splashscreen.h"
|
||||
#include "masternodeconfig.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#if QT_VERSION < 0x050000
|
||||
@ -154,6 +155,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
||||
|
||||
// Process masternode config
|
||||
masternodeConfig.read(GetMasternodeConfigFile());
|
||||
|
||||
// Application identification (must be set before OptionsModel is initialized,
|
||||
// as it is used to locate QSettings)
|
||||
QApplication::setOrganizationName("DarkCoin");
|
||||
|
@ -9,12 +9,10 @@
|
||||
#include "init.h"
|
||||
#include "masternode.h"
|
||||
#include "activemasternode.h"
|
||||
#include "masternodeconfig.h"
|
||||
#include "bitcoinrpc.h"
|
||||
|
||||
#include <fstream>
|
||||
using namespace json_spirit;
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
Value darksend(const Array& params, bool fHelp)
|
||||
@ -75,7 +73,7 @@ Value getpoolinfo(const Array& params, bool fHelp)
|
||||
"Returns an object containing anonymous pool-related information.");
|
||||
|
||||
Object obj;
|
||||
obj.push_back(Pair("connected_to_masternode", activeMasternode.masterNodeAddr));
|
||||
obj.push_back(Pair("connected_to_masternode", activeMasternode.service.ToString()));
|
||||
obj.push_back(Pair("current_masternode", GetCurrentMasterNode()));
|
||||
obj.push_back(Pair("state", darkSendPool.GetState()));
|
||||
obj.push_back(Pair("entries", darkSendPool.GetEntriesCount()));
|
||||
@ -90,10 +88,10 @@ Value masternode(const Array& params, bool fHelp)
|
||||
strCommand = params[0].get_str();
|
||||
|
||||
if (fHelp ||
|
||||
(strCommand != "start" && strCommand != "start-many" && strCommand != "stop" && strCommand != "list" && strCommand != "count" && strCommand != "enforce"
|
||||
(strCommand != "start" && strCommand != "start-alias" && strCommand != "start-many" && strCommand != "stop" && strCommand != "stop-alias" && strCommand != "stop-many" && strCommand != "list" && strCommand != "list-conf" && strCommand != "count" && strCommand != "enforce"
|
||||
&& strCommand != "debug" && strCommand != "current" && strCommand != "winners" && strCommand != "genkey" && strCommand != "connect"))
|
||||
throw runtime_error(
|
||||
"masternode <start|start-many|stop|list|count|debug|current|winners|genkey|enforce> passphrase\n");
|
||||
"masternode <start|start-alias|start-many|stop|stop-alias|stop-many|list|list-conf|count|debug|current|winners|genkey|enforce> passphrase\n");
|
||||
|
||||
if (strCommand == "stop")
|
||||
{
|
||||
@ -115,15 +113,126 @@ Value masternode(const Array& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
activeMasternode.RegisterAsMasterNode(true);
|
||||
std::string errorMessage;
|
||||
if(!activeMasternode.StopMasterNode(errorMessage)) {
|
||||
return "stop failed: " + errorMessage;
|
||||
}
|
||||
pwalletMain->Lock();
|
||||
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_STOPPED) return "successfully stopped masternode";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_NOT_CAPABLE) return "not capable masternode";
|
||||
if(activeMasternode.status == MASTERNODE_STOPPED) return "successfully stopped masternode";
|
||||
if(activeMasternode.status == MASTERNODE_NOT_CAPABLE) return "not capable masternode";
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
if (strCommand == "stop-alias")
|
||||
{
|
||||
if (params.size() < 2){
|
||||
throw runtime_error(
|
||||
"command needs at least 2 parameters\n");
|
||||
}
|
||||
|
||||
std::string alias = params[1].get_str().c_str();
|
||||
|
||||
if(pwalletMain->IsLocked()) {
|
||||
SecureString strWalletPass;
|
||||
strWalletPass.reserve(100);
|
||||
|
||||
if (params.size() == 3){
|
||||
strWalletPass = params[2].get_str().c_str();
|
||||
} else {
|
||||
throw runtime_error(
|
||||
"Your wallet is locked, passphrase is required\n");
|
||||
}
|
||||
|
||||
if(!pwalletMain->Unlock(strWalletPass)){
|
||||
return "incorrect passphrase";
|
||||
}
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
Object statusObj;
|
||||
statusObj.push_back(Pair("alias", alias));
|
||||
|
||||
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
|
||||
if(mne.getAlias() == alias) {
|
||||
found = true;
|
||||
std::string errorMessage;
|
||||
bool result = activeMasternode.StopMasterNode(mne.getIp(), mne.getPrivKey(), errorMessage);
|
||||
|
||||
statusObj.push_back(Pair("result", result ? "successful" : "failed"));
|
||||
if(!result) {
|
||||
statusObj.push_back(Pair("errorMessage", errorMessage));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
statusObj.push_back(Pair("result", "failed"));
|
||||
statusObj.push_back(Pair("errorMessage", "could not find alias in config. Verify with list-conf."));
|
||||
}
|
||||
|
||||
pwalletMain->Lock();
|
||||
return statusObj;
|
||||
}
|
||||
|
||||
if (strCommand == "stop-many")
|
||||
{
|
||||
if(pwalletMain->IsLocked()) {
|
||||
SecureString strWalletPass;
|
||||
strWalletPass.reserve(100);
|
||||
|
||||
if (params.size() == 2){
|
||||
strWalletPass = params[1].get_str().c_str();
|
||||
} else {
|
||||
throw runtime_error(
|
||||
"Your wallet is locked, passphrase is required\n");
|
||||
}
|
||||
|
||||
if(!pwalletMain->Unlock(strWalletPass)){
|
||||
return "incorrect passphrase";
|
||||
}
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
int successful = 0;
|
||||
int fail = 0;
|
||||
|
||||
|
||||
Object resultsObj;
|
||||
|
||||
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
|
||||
total++;
|
||||
|
||||
std::string errorMessage;
|
||||
bool result = activeMasternode.StopMasterNode(mne.getIp(), mne.getPrivKey(), errorMessage);
|
||||
|
||||
Object statusObj;
|
||||
statusObj.push_back(Pair("alias", mne.getAlias()));
|
||||
statusObj.push_back(Pair("result", result ? "successful" : "failed"));
|
||||
|
||||
if(result) {
|
||||
successful++;
|
||||
} else {
|
||||
fail++;
|
||||
statusObj.push_back(Pair("errorMessage", errorMessage));
|
||||
}
|
||||
|
||||
resultsObj.push_back(Pair("status", statusObj));
|
||||
}
|
||||
pwalletMain->Lock();
|
||||
|
||||
Object returnObj;
|
||||
returnObj.push_back(Pair("overall", "Successfully stopped " + boost::lexical_cast<std::string>(successful) + " masternodes, failed to stop " +
|
||||
boost::lexical_cast<std::string>(fail) + ", total " + boost::lexical_cast<std::string>(total)));
|
||||
returnObj.push_back(Pair("detail", resultsObj));
|
||||
|
||||
return returnObj;
|
||||
|
||||
}
|
||||
|
||||
if (strCommand == "list")
|
||||
{
|
||||
std::string strCommand = "active";
|
||||
@ -187,57 +296,140 @@ Value masternode(const Array& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
activeMasternode.RegisterAsMasterNode(false);
|
||||
activeMasternode.status = MASTERNODE_NOT_PROCESSED; // TODO: consider better way
|
||||
std::string errorMessage;
|
||||
activeMasternode.ManageStatus();
|
||||
pwalletMain->Lock();
|
||||
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_REMOTELY_ENABLED) return "masternode started remotely";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_INPUT_TOO_NEW) return "masternode input must have at least 15 confirmations";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_STOPPED) return "masternode is stopped";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_IS_CAPABLE) return "successfully started masternode";
|
||||
if(activeMasternode.masternodePortOpen == MASTERNODE_PORT_NOT_OPEN) return "inbound port is not open. Please open it and try again. (19999 for testnet and 9999 for mainnet)";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_NOT_CAPABLE) return "not capable masternode";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_SYNC_IN_PROCESS) return "sync in process. Must wait until client is synced to start.";
|
||||
if(activeMasternode.status == MASTERNODE_REMOTELY_ENABLED) return "masternode started remotely";
|
||||
if(activeMasternode.status == MASTERNODE_INPUT_TOO_NEW) return "masternode input must have at least 15 confirmations";
|
||||
if(activeMasternode.status == MASTERNODE_STOPPED) return "masternode is stopped";
|
||||
if(activeMasternode.status == MASTERNODE_IS_CAPABLE) return "successfully started masternode";
|
||||
if(activeMasternode.status == MASTERNODE_NOT_CAPABLE) return "not capable masternode: " + activeMasternode.notCapableReason;
|
||||
if(activeMasternode.status == MASTERNODE_SYNC_IN_PROCESS) return "sync in process. Must wait until client is synced to start.";
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
if (strCommand == "start-alias")
|
||||
{
|
||||
if (params.size() < 2){
|
||||
throw runtime_error(
|
||||
"command needs at least 2 parameters\n");
|
||||
}
|
||||
|
||||
std::string alias = params[1].get_str().c_str();
|
||||
|
||||
if(pwalletMain->IsLocked()) {
|
||||
SecureString strWalletPass;
|
||||
strWalletPass.reserve(100);
|
||||
|
||||
if (params.size() == 3){
|
||||
strWalletPass = params[2].get_str().c_str();
|
||||
} else {
|
||||
throw runtime_error(
|
||||
"Your wallet is locked, passphrase is required\n");
|
||||
}
|
||||
|
||||
if(!pwalletMain->Unlock(strWalletPass)){
|
||||
return "incorrect passphrase";
|
||||
}
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
Object statusObj;
|
||||
statusObj.push_back(Pair("alias", alias));
|
||||
|
||||
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
|
||||
if(mne.getAlias() == alias) {
|
||||
found = true;
|
||||
std::string errorMessage;
|
||||
bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage);
|
||||
|
||||
statusObj.push_back(Pair("result", result ? "successful" : "failed"));
|
||||
if(!result) {
|
||||
statusObj.push_back(Pair("errorMessage", errorMessage));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
statusObj.push_back(Pair("result", "failed"));
|
||||
statusObj.push_back(Pair("errorMessage", "could not find alias in config. Verify with list-conf."));
|
||||
}
|
||||
|
||||
pwalletMain->Lock();
|
||||
return statusObj;
|
||||
|
||||
}
|
||||
|
||||
if (strCommand == "start-many")
|
||||
{
|
||||
boost::filesystem::path pathDebug = GetDataDir() / "masternode.conf";
|
||||
std::ifstream infile(pathDebug.string().c_str());
|
||||
if(pwalletMain->IsLocked()) {
|
||||
SecureString strWalletPass;
|
||||
strWalletPass.reserve(100);
|
||||
|
||||
std::string line;
|
||||
int total = 0;
|
||||
int successful = 0;
|
||||
int fail = 0;
|
||||
while (std::getline(infile, line))
|
||||
{
|
||||
std::istringstream iss(line);
|
||||
std::string a, b;
|
||||
if (!(iss >> a >> b)) { break; } // error
|
||||
if (params.size() == 2){
|
||||
strWalletPass = params[1].get_str().c_str();
|
||||
} else {
|
||||
throw runtime_error(
|
||||
"Your wallet is locked, passphrase is required\n");
|
||||
}
|
||||
|
||||
total++;
|
||||
if(activeMasternode.RegisterAsMasterNodeRemoteOnly(a, b)){
|
||||
successful++;
|
||||
} else {
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
|
||||
printf(" Successfully started %d masternodes, failed to start %d, total %d\n", successful, fail, total);
|
||||
return "";
|
||||
if(!pwalletMain->Unlock(strWalletPass)){
|
||||
return "incorrect passphrase";
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
|
||||
mnEntries = masternodeConfig.getEntries();
|
||||
|
||||
int total = 0;
|
||||
int successful = 0;
|
||||
int fail = 0;
|
||||
|
||||
Object resultsObj;
|
||||
|
||||
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
|
||||
total++;
|
||||
|
||||
std::string errorMessage;
|
||||
bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage);
|
||||
|
||||
Object statusObj;
|
||||
statusObj.push_back(Pair("alias", mne.getAlias()));
|
||||
statusObj.push_back(Pair("result", result ? "succesful" : "failed"));
|
||||
|
||||
if(result) {
|
||||
successful++;
|
||||
} else {
|
||||
fail++;
|
||||
statusObj.push_back(Pair("errorMessage", errorMessage));
|
||||
}
|
||||
|
||||
resultsObj.push_back(Pair("status", statusObj));
|
||||
}
|
||||
pwalletMain->Lock();
|
||||
|
||||
Object returnObj;
|
||||
returnObj.push_back(Pair("overall", "Successfully started " + boost::lexical_cast<std::string>(successful) + " masternodes, failed to start " +
|
||||
boost::lexical_cast<std::string>(fail) + ", total " + boost::lexical_cast<std::string>(total)));
|
||||
returnObj.push_back(Pair("detail", resultsObj));
|
||||
|
||||
return returnObj;
|
||||
|
||||
}
|
||||
|
||||
if (strCommand == "debug")
|
||||
{
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_REMOTELY_ENABLED) return "masternode started remotely";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_INPUT_TOO_NEW) return "masternode input must have at least 15 confirmations";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_IS_CAPABLE) return "successfully started masternode";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_STOPPED) return "masternode is stopped";
|
||||
if(activeMasternode.masternodePortOpen == MASTERNODE_PORT_NOT_OPEN) return "inbound port is not open. Please open it and try again. (19999 for testnet and 9999 for mainnet)";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_NOT_CAPABLE) return "not capable masternode";
|
||||
if(activeMasternode.isCapableMasterNode == MASTERNODE_SYNC_IN_PROCESS) return "sync in process. Must wait until client is synced to start.";
|
||||
if(activeMasternode.status == MASTERNODE_REMOTELY_ENABLED) return "masternode started remotely";
|
||||
if(activeMasternode.status == MASTERNODE_INPUT_TOO_NEW) return "masternode input must have at least 15 confirmations";
|
||||
if(activeMasternode.status == MASTERNODE_IS_CAPABLE) return "successfully started masternode";
|
||||
if(activeMasternode.status == MASTERNODE_STOPPED) return "masternode is stopped";
|
||||
if(activeMasternode.status == MASTERNODE_NOT_CAPABLE) return "not capable masternode: " + activeMasternode.notCapableReason;
|
||||
if(activeMasternode.status == MASTERNODE_SYNC_IN_PROCESS) return "sync in process. Must wait until client is synced to start.";
|
||||
|
||||
CTxIn vin = CTxIn();
|
||||
CPubKey pubkey = CScript();
|
||||
@ -318,6 +510,26 @@ Value masternode(const Array& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
if(strCommand == "list-conf")
|
||||
{
|
||||
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
|
||||
mnEntries = masternodeConfig.getEntries();
|
||||
|
||||
Object resultObj;
|
||||
|
||||
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
|
||||
Object mnObj;
|
||||
mnObj.push_back(Pair("alias", mne.getAlias()));
|
||||
mnObj.push_back(Pair("address", mne.getIp()));
|
||||
mnObj.push_back(Pair("privateKey", mne.getPrivKey()));
|
||||
mnObj.push_back(Pair("txHash", mne.getTxHash()));
|
||||
mnObj.push_back(Pair("outputIndex", mne.getOutputIndex()));
|
||||
resultObj.push_back(Pair("masternode", mnObj));
|
||||
}
|
||||
|
||||
return resultObj;
|
||||
}
|
||||
|
||||
return Value::null;
|
||||
}
|
||||
|
||||
|
@ -1127,6 +1127,13 @@ boost::filesystem::path GetConfigFile()
|
||||
return pathConfigFile;
|
||||
}
|
||||
|
||||
boost::filesystem::path GetMasternodeConfigFile()
|
||||
{
|
||||
boost::filesystem::path pathConfigFile(GetArg("-mnconf", "masternode.conf"));
|
||||
if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile;
|
||||
return pathConfigFile;
|
||||
}
|
||||
|
||||
void ReadConfigFile(map<string, string>& mapSettingsRet,
|
||||
map<string, vector<string> >& mapMultiSettingsRet)
|
||||
{
|
||||
|
@ -210,6 +210,7 @@ bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
|
||||
boost::filesystem::path GetDefaultDataDir();
|
||||
const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
|
||||
boost::filesystem::path GetConfigFile();
|
||||
boost::filesystem::path GetMasternodeConfigFile();
|
||||
boost::filesystem::path GetPidFile();
|
||||
#ifndef WIN32
|
||||
void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
|
||||
|
@ -1201,26 +1201,6 @@ static void ApproximateBestSubset(vector<pair<int64, pair<const CWalletTx*,unsig
|
||||
}
|
||||
}
|
||||
|
||||
/* select coins with 1 unspent output */
|
||||
bool CWallet::SelectCoinsMasternode(CTxIn& vin, int64& nValueRet, CScript& pubScript) const
|
||||
{
|
||||
CCoinControl *coinControl=NULL;
|
||||
vector<COutput> vCoins;
|
||||
AvailableCoins(vCoins, true, coinControl, ALL_COINS);
|
||||
|
||||
BOOST_FOREACH(const COutput& out, vCoins)
|
||||
{
|
||||
if(out.tx->vout[out.i].nValue == 1000*COIN){ //exactly
|
||||
vin = CTxIn(out.tx->GetHash(),out.i);
|
||||
pubScript = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey
|
||||
nValueRet = out.tx->vout[out.i].nValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
|
||||
set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user