Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions doc/masternode_conf.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ BITCOIN_CORE_H = \
limitedmap.h \
main.h \
masternode.h \
masternodeconfig.h \
miner.h \
mruset.h \
netbase.h \
Expand Down Expand Up @@ -147,6 +148,7 @@ libdarkcoin_common_a_SOURCES = \
core.cpp \
darksend.cpp \
masternode.cpp \
masternodeconfig.cpp \
instantx.cpp \
hash.cpp \
key.cpp \
Expand Down
470 changes: 282 additions & 188 deletions src/activemasternode.cpp

Large diffs are not rendered by default.

49 changes: 28 additions & 21 deletions src/activemasternode.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,36 +18,44 @@
class CActiveMasternode
{
public:
CTxIn vinMasternode;
CPubKey pubkeyMasterNode;
CPubKey pubkeyMasterNode2;

std::string strMasterNodeSignMessage;
std::vector<unsigned char> vchMasterNodeSignature;
// Initialized by init.cpp
// Keys for the main masternode
CPubKey pubKeyMasternode;

std::string masterNodeAddr;
CService masterNodeSignAddr;
// Initialized while registering masternode
CTxIn vin;
CService service;

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
#endif
4 changes: 4 additions & 0 deletions src/darkcoind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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");
Expand Down
16 changes: 8 additions & 8 deletions src/darksend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -2102,6 +2102,8 @@ void ThreadCheckDarkSendPool()
RenameThread("bitcoin-darksend");

unsigned int c = 0;
std::string errorMessage;

while (true)
{
c++;
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/darksend.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#define DARKSEND_H

#include "core.h"
#include "masternode.h"
#include "main.h"
#include "masternode.h"
#include "activemasternode.h"

class CTxIn;
Expand Down
2 changes: 1 addition & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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."));
Expand Down
8 changes: 4 additions & 4 deletions src/instantx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -456,4 +456,4 @@ void CTransactionLock::AddSignature(CConsensusVote cv)
int CTransactionLock::CountSignatures()
{
return vecConsensusVotes.size();
}
}
17 changes: 9 additions & 8 deletions src/masternode.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


#include "masternode.h"
#include "activemasternode.h"
#include "darksend.h"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -210,8 +210,9 @@ 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
if(mn.lastDseep < sigTime){
// 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);

std::string errorMessage = "";
Expand Down
32 changes: 32 additions & 0 deletions src/masternodeconfig.cpp
Original file line number Diff line number Diff line change
@@ -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();
}
Loading