Merge pull request #75 from freynder/start-many-enh-v0.11.0.x
Improve support for start-many
This commit is contained in:
commit
3a8545fa28
26
doc/masternode_conf.md
Normal file
26
doc/masternode_conf.md
Normal file
@ -0,0 +1,26 @@
|
||||
Multi masternode config
|
||||
=======================
|
||||
|
||||
The multi masternode config allows to control multiple masternodes from a single wallet. The wallet needs to have a valid collaral input of 1000 coins for each masternode. To use this, place a file named masternode.conf in the data directory of your install.
|
||||
|
||||
The new masternode.conf format consists of a space seperated text file. Each line consisting of an alias, address, private key, collateral output transaction and collateral output index.
|
||||
|
||||
Example:
|
||||
```
|
||||
mn1 127.0.0.2:19999 93HaYBVUCYjEMeeH1Y4sBGLALQZE1Yc1K64xiqgX37tGBDQL8Xg 2bcd3c84c84f87eaa86e4e56834c92927a07f9e18718810b92e0d0324456a67c 0
|
||||
mn2 127.0.0.3:19999 93WaAb3htPJEV8E9aQcN23Jt97bPex7YvWfgMDTUdWJvzmrMqey aa9f1034d973377a5e733272c3d0eced1de22555ad45d6b24abadff8087948d4 0
|
||||
mn3 127.0.0.4:19999 92Da1aYg6sbenP6uwskJgEY2XWB5LwJ7bXRqc3UPeShtHWJDjDv db478e78e3aefaa8c12d12ddd0aeace48c3b451a8b41c570d0ee375e2a02dfd9 1
|
||||
```
|
||||
|
||||
In the example above, the collateral for mn1 consists of transaction:
|
||||
http://test.explorer.darkcoin.fr/tx/2bcd3c84c84f87eaa86e4e56834c92927a07f9e18718810b92e0d0324456a67c
|
||||
output index 0 has amount 1000
|
||||
|
||||
The following new RPC commands are supported:
|
||||
* list-conf: shows the parsed masternode.conf
|
||||
* start-alias \<alias\>
|
||||
* stop-alias \<alias\>
|
||||
* start-many
|
||||
* stop-many
|
||||
|
||||
When using the multi masternode setup, it is advised to run the wallet with 'masternode=0' as it is not needed anymore.
|
@ -51,6 +51,7 @@ BITCOIN_CORE_H = \
|
||||
limitedmap.h \
|
||||
main.h \
|
||||
masternode.h \
|
||||
masternodeconfig.h \
|
||||
miner.h \
|
||||
mruset.h \
|
||||
netbase.h \
|
||||
@ -147,6 +148,7 @@ libdarkcoin_common_a_SOURCES = \
|
||||
core.cpp \
|
||||
darksend.cpp \
|
||||
masternode.cpp \
|
||||
masternodeconfig.cpp \
|
||||
instantx.cpp \
|
||||
hash.cpp \
|
||||
key.cpp \
|
||||
|
@ -4,285 +4,333 @@
|
||||
#include "activemasternode.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
//
|
||||
// Bootup the masternode, look for a 1000DRK input and register on the network
|
||||
//
|
||||
void CActiveMasternode::RegisterAsMasterNode(bool stop)
|
||||
void CActiveMasternode::ManageStatus()
|
||||
{
|
||||
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((Params().NetworkID() == CChainParams::TESTNET && masterNodeSignAddr.GetPort() != 19999) || (!(Params().NetworkID() == CChainParams::TESTNET) && masterNodeSignAddr.GetPort() != 9999)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Invalid port\n");
|
||||
isCapableMasterNode = MASTERNODE_NOT_CAPABLE;
|
||||
if((Params().NetworkID() == CChainParams::TESTNET && service.GetPort() != 19999) || (!(Params().NetworkID() == CChainParams::TESTNET) && 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;
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n");
|
||||
|
||||
masterNodeSignatureTime = GetAdjustedTime();
|
||||
status = MASTERNODE_IS_CAPABLE;
|
||||
notCapableReason = "";
|
||||
|
||||
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);
|
||||
pwalletMain->LockCoin(vin.prevout);
|
||||
|
||||
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, SecretKey)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Sign message failed\n");
|
||||
return;
|
||||
}
|
||||
// send to all nodes
|
||||
CPubKey pubKeyMasternode;
|
||||
CKey keyMasternode;
|
||||
|
||||
if(!darkSendSigner.VerifyMessage(pubkeyMasterNode, vchMasterNodeSignature, strMessage, errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Verify message failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(isCapableMasterNode != MASTERNODE_IS_CAPABLE && isCapableMasterNode != MASTERNODE_REMOTELY_ENABLED) return;
|
||||
|
||||
masterNodeSignatureTime = GetAdjustedTime();
|
||||
|
||||
std::string strMessage = masterNodeSignAddr.ToString() + boost::lexical_cast<std::string>(masterNodeSignatureTime) + boost::lexical_cast<std::string>(stop);
|
||||
|
||||
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, key2)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Sign message failed\n");
|
||||
LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!darkSendSigner.VerifyMessage(pubkey2, vchMasterNodeSignature, strMessage, errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Verify message failed\n");
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
//send to all peers
|
||||
if(!Dseep(errorMessage)) {
|
||||
LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s", errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) {
|
||||
LogPrintf("CActiveMasternode::StopMasterNode() - Error: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_t 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;
|
||||
}
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNode() - Masternode input = %s\n", vinMasternode.ToString().c_str());
|
||||
|
||||
if (stop) isCapableMasterNode = MASTERNODE_STOPPED;
|
||||
|
||||
//relay to all peers
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
pnode->PushMessage("dseep", vinMasternode, vchMasterNodeSignature, masterNodeSignatureTime, stop);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Address %s MasterNodePrivKey %s\n", strMasterNodeAddr.c_str(), strMasterNodePrivKey.c_str());
|
||||
|
||||
std::string errorMessage;
|
||||
|
||||
CKey key2;
|
||||
CPubKey pubkey2;
|
||||
|
||||
|
||||
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, key2, pubkey2))
|
||||
{
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Invalid masternodeprivkey: '%s'\n", errorMessage.c_str());
|
||||
// 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;
|
||||
}
|
||||
|
||||
CService masterNodeSignAddr = CService(strMasterNodeAddr);
|
||||
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes){
|
||||
if(mn.addr == masterNodeSignAddr){
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Address in use\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if((Params().NetworkID() == CChainParams::TESTNET && masterNodeSignAddr.GetPort() != 19999) || (!(Params().NetworkID() == CChainParams::TESTNET) && masterNodeSignAddr.GetPort() != 9999)) {
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - Invalid port\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
//send to all peers
|
||||
LogPrintf("CActiveMasternode::Dseep() - SendDarkSendElectionEntryPing vin = %s\n", vin.ToString().c_str());
|
||||
SendDarkSendElectionEntryPing(vin, vchMasterNodeSignature, masterNodeSignatureTime, stop);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode))
|
||||
{
|
||||
LogPrintf("CActiveMasternode::Register() - Error upon calling SetKey: %s\n", errorMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintf("CActiveMasternode::RegisterAsMasterNodeRemoteOnly() - No suitable vin found\n");
|
||||
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_t masterNodeSignatureTime = GetAdjustedTime();
|
||||
|
||||
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.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyCollateralAddress)) {
|
||||
retErrorMessage = "sign message failed: " + errorMessage;
|
||||
LogPrintf("CActiveMasternode::Register() - Error: %s\n", retErrorMessage.c_str());
|
||||
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);
|
||||
}
|
||||
|
||||
//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);
|
||||
|
||||
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, std::string strTxHash, std::string strOutputIndex) {
|
||||
CScript pubScript;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we have a selected output, retrieve the associated info
|
||||
return GetVinFromOutput(*selectedOutput, vin, pubkey, secretKey);
|
||||
}
|
||||
|
||||
|
||||
bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey)
|
||||
{
|
||||
int64_t nValueIn = 0;
|
||||
// Extract masternode vin information from output
|
||||
bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey) {
|
||||
|
||||
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;
|
||||
}
|
||||
vin = CTxIn(out.tx->GetHash(),out.i);
|
||||
pubScript = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey
|
||||
|
||||
CTxDestination address1;
|
||||
ExtractDestination(pubScript, 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_t 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
|
||||
@ -19,36 +18,44 @@
|
||||
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_t 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_t sigTime, CService& addr);
|
||||
bool EnableHotColdMasterNode(CTxIn& vin, CService& addr);
|
||||
};
|
||||
|
||||
#endif
|
@ -11,6 +11,7 @@
|
||||
#include "noui.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "masternodeconfig.h"
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
@ -78,6 +79,9 @@ bool AppInit(int argc, char* argv[])
|
||||
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
masternodeConfig.read(GetMasternodeConfigFile());
|
||||
|
||||
// Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause)
|
||||
if (!SelectParamsFromCommandLine()) {
|
||||
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
|
||||
|
@ -110,7 +110,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;
|
||||
|
||||
@ -798,7 +798,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();
|
||||
@ -1850,7 +1850,7 @@ bool CDarkSendPool::IsCompatibleWithSession(int64_t nDenom, CTransaction txColla
|
||||
//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();
|
||||
@ -2102,6 +2102,8 @@ void ThreadCheckDarkSendPool()
|
||||
RenameThread("bitcoin-darksend");
|
||||
|
||||
unsigned int c = 0;
|
||||
std::string errorMessage;
|
||||
|
||||
while (true)
|
||||
{
|
||||
c++;
|
||||
@ -2150,16 +2152,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)
|
||||
|
@ -7,8 +7,8 @@
|
||||
#define DARKSEND_H
|
||||
|
||||
#include "core.h"
|
||||
#include "masternode.h"
|
||||
#include "main.h"
|
||||
#include "masternode.h"
|
||||
#include "activemasternode.h"
|
||||
|
||||
class CTxIn;
|
||||
|
@ -1113,7 +1113,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."));
|
||||
|
@ -210,7 +210,7 @@ void DoConsensusVote(CTransaction& tx, bool approved, int64_t 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)
|
||||
{
|
||||
@ -228,7 +228,7 @@ void DoConsensusVote(CTransaction& tx, bool approved, int64_t nBlockHeight)
|
||||
}
|
||||
|
||||
CConsensusVote ctx;
|
||||
ctx.vinMasternode = activeMasternode.vinMasternode;
|
||||
ctx.vinMasternode = activeMasternode.vin;
|
||||
ctx.approved = approved;
|
||||
ctx.txHash = tx.GetHash();
|
||||
ctx.nBlockHeight = nBlockHeight;
|
||||
@ -277,7 +277,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;
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
#include "masternode.h"
|
||||
#include "activemasternode.h"
|
||||
#include "darksend.h"
|
||||
@ -164,10 +162,10 @@ void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream
|
||||
mn.UpdateLastSeen(lastUpdated);
|
||||
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 it matches our masternodeprivkey, then we've been remotely activated
|
||||
if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){
|
||||
activeMasternode.EnableHotColdMasterNode(vin, addr);
|
||||
}
|
||||
|
||||
if(count == -1 && !isLocal)
|
||||
RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
|
||||
@ -196,6 +194,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;
|
||||
@ -210,6 +210,7 @@ void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream
|
||||
|
||||
BOOST_FOREACH(CMasterNode& mn, darkSendMasterNodes) {
|
||||
if(mn.vin.prevout == vin.prevout) {
|
||||
// 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);
|
||||
|
32
src/masternodeconfig.cpp
Normal file
32
src/masternodeconfig.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#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());
|
||||
continue;
|
||||
}
|
||||
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_ */
|
||||
|
@ -12,6 +12,7 @@
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#endif
|
||||
#include "masternode.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
19
src/net.cpp
19
src/net.cpp
@ -1911,6 +1911,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_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t 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_t nNow, const bool stop)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
@ -1922,6 +1931,15 @@ void RelayDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned
|
||||
}
|
||||
}
|
||||
|
||||
void SendDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t 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);
|
||||
@ -1931,7 +1949,6 @@ void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, co
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CNode::RecordBytesRecv(uint64_t bytes)
|
||||
{
|
||||
LOCK(cs_totalBytesRecv);
|
||||
|
@ -764,7 +764,9 @@ void RelayDarkSendFinalTransaction(const int sessionID, const CTransaction& txNe
|
||||
void RelayDarkSendIn(const std::vector<CTxIn>& in, const int64_t& 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_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t lastUpdated, const int protocolVersion);
|
||||
void SendDarkSendElectionEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t lastUpdated, const int protocolVersion);
|
||||
void RelayDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t nNow, const bool stop);
|
||||
void SendDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t nNow, const bool stop);
|
||||
void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage);
|
||||
void RelayDarkSendMasterNodeContestant();
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "paymentserver.h"
|
||||
#include "walletmodel.h"
|
||||
#endif
|
||||
#include "masternodeconfig.h"
|
||||
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
@ -533,6 +534,8 @@ int main(int argc, char *argv[])
|
||||
return false;
|
||||
}
|
||||
|
||||
masternodeConfig.read(GetMasternodeConfigFile());
|
||||
|
||||
/// 7. Determine network (and switch to network specific options)
|
||||
// - Do not call Params() before this step
|
||||
// - Do this after parsing the configuration file, as the network can be switched there
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "init.h"
|
||||
#include "masternode.h"
|
||||
#include "activemasternode.h"
|
||||
#include "masternodeconfig.h"
|
||||
#include "rpcserver.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
@ -83,6 +84,7 @@ Value getpoolinfo(const Array& params, bool fHelp)
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
Value masternode(const Array& params, bool fHelp)
|
||||
{
|
||||
string strCommand;
|
||||
@ -90,10 +92,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 +117,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 +300,139 @@ 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);
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
|
||||
mnEntries = masternodeConfig.getEntries();
|
||||
|
||||
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
|
||||
|
||||
Object resultsObj;
|
||||
|
||||
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
|
||||
total++;
|
||||
if(activeMasternode.RegisterAsMasterNodeRemoteOnly(a, b)){
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
printf(" Successfully started %d masternodes, failed to start %d, total %d\n", successful, fail, total);
|
||||
return "";
|
||||
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 +513,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;
|
||||
}
|
||||
|
||||
|
@ -1033,6 +1033,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)
|
||||
{
|
||||
|
@ -195,6 +195,7 @@ bool TryCreateDirectory(const boost::filesystem::path& p);
|
||||
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);
|
||||
|
@ -10,10 +10,12 @@
|
||||
#include "checkpoints.h"
|
||||
#include "coincontrol.h"
|
||||
#include "net.h"
|
||||
#include "darksend.h"
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Settings
|
||||
@ -1246,25 +1248,6 @@ static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,uns
|
||||
}
|
||||
}
|
||||
|
||||
/* select coins with 1 unspent output */
|
||||
bool CWallet::SelectCoinsMasternode(CTxIn& vin, int64_t& 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_t nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
|
||||
set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const
|
||||
|
@ -7,7 +7,6 @@
|
||||
#define BITCOIN_WALLET_H
|
||||
|
||||
#include "core.h"
|
||||
#include "darksend.h"
|
||||
#include "crypter.h"
|
||||
#include "key.h"
|
||||
#include "keystore.h"
|
||||
|
Loading…
Reference in New Issue
Block a user