merged mkinney-v0.11.2

This commit is contained in:
Evan Duffield 2015-03-05 08:18:45 -07:00
commit 9aca26d220
9 changed files with 254 additions and 218 deletions

View File

@ -6,7 +6,7 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
// //
// Bootup the masternode, look for a 1000DRK input and register on the network // Bootup the Masternode, look for a 1000DRK input and register on the network
// //
void CActiveMasternode::ManageStatus() void CActiveMasternode::ManageStatus()
{ {
@ -20,7 +20,7 @@ void CActiveMasternode::ManageStatus()
bool fIsInitialDownload = IsInitialBlockDownload(); bool fIsInitialDownload = IsInitialBlockDownload();
if(fIsInitialDownload) { if(fIsInitialDownload) {
status = MASTERNODE_SYNC_IN_PROCESS; status = MASTERNODE_SYNC_IN_PROCESS;
LogPrintf("CActiveMasternode::ManageStatus() - Sync in progress. Must wait until sync is complete to start masternode.\n"); LogPrintf("CActiveMasternode::ManageStatus() - Sync in progress. Must wait until sync is complete to start Masternode.\n");
return; return;
} }
@ -31,7 +31,7 @@ void CActiveMasternode::ManageStatus()
if(status == MASTERNODE_NOT_PROCESSED) { if(status == MASTERNODE_NOT_PROCESSED) {
if(strMasterNodeAddr.empty()) { if(strMasterNodeAddr.empty()) {
if(!GetLocal(service)) { if(!GetLocal(service)) {
notCapableReason = "Can't detect external address. Please use the masternodeaddr configuration option."; notCapableReason = "Can't detect external address. Please use the Masternodeaddr configuration option.";
status = MASTERNODE_NOT_CAPABLE; status = MASTERNODE_NOT_CAPABLE;
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str()); LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
return; return;
@ -119,7 +119,7 @@ void CActiveMasternode::ManageStatus()
} }
} }
// Send stop dseep to network for remote masternode // Send stop dseep to network for remote Masternode
bool CActiveMasternode::StopMasterNode(std::string strService, std::string strKeyMasternode, std::string& errorMessage) { bool CActiveMasternode::StopMasterNode(std::string strService, std::string strKeyMasternode, std::string& errorMessage) {
CTxIn vin; CTxIn vin;
CKey keyMasternode; CKey keyMasternode;
@ -133,10 +133,10 @@ bool CActiveMasternode::StopMasterNode(std::string strService, std::string strKe
return StopMasterNode(vin, CService(strService), keyMasternode, pubKeyMasternode, errorMessage); return StopMasterNode(vin, CService(strService), keyMasternode, pubKeyMasternode, errorMessage);
} }
// Send stop dseep to network for main masternode // Send stop dseep to network for main Masternode
bool CActiveMasternode::StopMasterNode(std::string& errorMessage) { bool CActiveMasternode::StopMasterNode(std::string& errorMessage) {
if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) { if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) {
errorMessage = "masternode is not in a running status"; errorMessage = "Masternode is not in a running status";
LogPrintf("CActiveMasternode::StopMasterNode() - Error: %s\n", errorMessage.c_str()); LogPrintf("CActiveMasternode::StopMasterNode() - Error: %s\n", errorMessage.c_str());
return false; return false;
} }
@ -155,7 +155,7 @@ bool CActiveMasternode::StopMasterNode(std::string& errorMessage) {
return StopMasterNode(vin, service, keyMasternode, pubKeyMasternode, errorMessage); return StopMasterNode(vin, service, keyMasternode, pubKeyMasternode, errorMessage);
} }
// Send stop dseep to network for any masternode // Send stop dseep to network for any Masternode
bool CActiveMasternode::StopMasterNode(CTxIn vin, CService service, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage) { bool CActiveMasternode::StopMasterNode(CTxIn vin, CService service, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage) {
pwalletMain->UnlockCoin(vin.prevout); pwalletMain->UnlockCoin(vin.prevout);
return Dseep(vin, service, keyMasternode, pubKeyMasternode, errorMessage, true); return Dseep(vin, service, keyMasternode, pubKeyMasternode, errorMessage, true);
@ -163,7 +163,7 @@ bool CActiveMasternode::StopMasterNode(CTxIn vin, CService service, CKey keyMast
bool CActiveMasternode::Dseep(std::string& errorMessage) { bool CActiveMasternode::Dseep(std::string& errorMessage) {
if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) { if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) {
errorMessage = "masternode is not in a running status"; errorMessage = "Masternode is not in a running status";
LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", errorMessage.c_str()); LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", errorMessage.c_str());
return false; return false;
} }
@ -200,7 +200,7 @@ bool CActiveMasternode::Dseep(CTxIn vin, CService service, CKey keyMasternode, C
return false; return false;
} }
// Update Last Seen timestamp in masternode list // Update Last Seen timestamp in Masternode list
CMasternode* pmn = mnodeman.Find(vin); CMasternode* pmn = mnodeman.Find(vin);
if(pmn != NULL) if(pmn != NULL)
{ {
@ -208,8 +208,8 @@ bool CActiveMasternode::Dseep(CTxIn vin, CService service, CKey keyMasternode, C
} }
else else
{ {
// Seems like we are trying to send a ping while the masternode is not registered in the network // 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(); 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()); LogPrintf("CActiveMasternode::Dseep() - Error: %s\n", retErrorMessage.c_str());
status = MASTERNODE_NOT_CAPABLE; status = MASTERNODE_NOT_CAPABLE;
notCapableReason = retErrorMessage; notCapableReason = retErrorMessage;
@ -270,7 +270,7 @@ bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateral
CMasternode* pmn = mnodeman.Find(vin); CMasternode* pmn = mnodeman.Find(vin);
if(pmn == NULL) if(pmn == NULL)
{ {
LogPrintf("CActiveMasternode::Register() - Adding to masternode list service: %s - vin: %s\n", service.ToString().c_str(), vin.ToString().c_str()); 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); CMasternode mn(service, vin, pubKeyCollateralAddress, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyMasternode, PROTOCOL_VERSION);
mn.UpdateLastSeen(masterNodeSignatureTime); mn.UpdateLastSeen(masterNodeSignatureTime);
mnodeman.Add(mn); mnodeman.Add(mn);
@ -327,7 +327,7 @@ bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secr
} }
// Extract masternode vin information from output // Extract Masternode vin information from output
bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey) { bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey) {
CScript pubScript; CScript pubScript;
@ -354,7 +354,7 @@ bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubke
return true; return true;
} }
// get all possible outputs for running masternode // get all possible outputs for running Masternode
vector<COutput> CActiveMasternode::SelectCoinsMasternode() vector<COutput> CActiveMasternode::SelectCoinsMasternode()
{ {
vector<COutput> vCoins; vector<COutput> vCoins;
@ -373,7 +373,7 @@ vector<COutput> CActiveMasternode::SelectCoinsMasternode()
return filteredCoins; return filteredCoins;
} }
// when starting a masternode, this can enable to run as a hot wallet with no funds // when starting a Masternode, this can enable to run as a hot wallet with no funds
bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& newVin, CService& newService) bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& newVin, CService& newService)
{ {
if(!fMasterNode) return false; if(!fMasterNode) return false;

View File

@ -14,15 +14,15 @@
#include "wallet.h" #include "wallet.h"
#include "darksend.h" #include "darksend.h"
// Responsible for activating the masternode and pinging the network // Responsible for activating the Masternode and pinging the network
class CActiveMasternode class CActiveMasternode
{ {
public: public:
// Initialized by init.cpp // Initialized by init.cpp
// Keys for the main masternode // Keys for the main Masternode
CPubKey pubKeyMasternode; CPubKey pubKeyMasternode;
// Initialized while registering masternode // Initialized while registering Masternode
CTxIn vin; CTxIn vin;
CService service; CService service;
@ -34,25 +34,33 @@ public:
status = MASTERNODE_NOT_PROCESSED; status = MASTERNODE_NOT_PROCESSED;
} }
void ManageStatus(); // manage status of main masternode /// Manage status of main Masternode
void ManageStatus();
bool Dseep(std::string& errorMessage); // ping for main masternode /// Ping for main Masternode
bool Dseep(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string &retErrorMessage, bool stop); // ping for any masternode bool Dseep(std::string& errorMessage);
/// Ping for any Masternode
bool Dseep(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string &retErrorMessage, bool stop);
bool StopMasterNode(std::string& errorMessage); // stop main masternode /// Stop main Masternode
bool StopMasterNode(std::string strService, std::string strKeyMasternode, std::string& errorMessage); // stop remote masternode bool StopMasterNode(std::string& errorMessage);
bool StopMasterNode(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string& errorMessage); // stop any masternode /// Stop remote Masternode
bool StopMasterNode(std::string strService, std::string strKeyMasternode, std::string& errorMessage);
/// Stop any Masternode
bool StopMasterNode(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string& errorMessage);
bool Register(std::string strService, std::string strKey, std::string txHash, std::string strOutputIndex, std::string& errorMessage); // register remote masternode /// Register remote Masternode
bool Register(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage); // register any masternode bool Register(std::string strService, std::string strKey, std::string txHash, std::string strOutputIndex, std::string& errorMessage);
/// Register any Masternode
bool Register(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage);
// get 1000DRK input that can be used for the 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);
bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex); bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex);
vector<COutput> SelectCoinsMasternode(); vector<COutput> SelectCoinsMasternode();
bool GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey); bool GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey);
// enable hot wallet mode (run a masternode with no funds) /// Enable hot wallet mode (run a Masternode with no funds)
bool EnableHotColdMasterNode(CTxIn& vin, CService& addr); bool EnableHotColdMasterNode(CTxIn& vin, CService& addr);
}; };

View File

@ -23,34 +23,34 @@ using namespace boost;
CCriticalSection cs_darksend; CCriticalSection cs_darksend;
/** The main object for accessing darksend */ // The main object for accessing Darksend
CDarksendPool darkSendPool; CDarksendPool darkSendPool;
/** A helper object for signing messages from masternodes */ // A helper object for signing messages from Masternodes
CDarkSendSigner darkSendSigner; CDarkSendSigner darkSendSigner;
/** The current darksends in progress on the network */ // The current Darksends in progress on the network
std::vector<CDarksendQueue> vecDarksendQueue; std::vector<CDarksendQueue> vecDarksendQueue;
/** Keep track of the used masternodes */ // Keep track of the used Masternodes
std::vector<CTxIn> vecMasternodesUsed; std::vector<CTxIn> vecMasternodesUsed;
// keep track of the scanning errors I've seen // Keep track of the scanning errors I've seen
map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes; map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes;
// // Keep track of the active Masternode
CActiveMasternode activeMasternode; CActiveMasternode activeMasternode;
// count peers we've requested the list from // Count peers we've requested the list from
int RequestedMasterNodeList = 0; int RequestedMasterNodeList = 0;
/* *** BEGIN DARKSEND MAGIC - DARKCOIN ********** /* *** BEGIN DARKSEND MAGIC - DARKCOIN **********
Copyright 2014, Darkcoin Developers Copyright 2014-2015, Darkcoin Developers
eduffield - evan@darkcoin.io eduffield - evan@darkcoin.io
udjinm6 - udjinm6@darkcoin.io udjinm6 - udjinm6@darkcoin.io
*/ */
void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{ {
if(fLiteMode) return; //disable all darksend/masternode related functionality if(fLiteMode) return; //disable all Darksend/Masternode related functionality
if(IsInitialBlockDownload()) return; if(IsInitialBlockDownload()) return;
if (strCommand == "dsa") { //DarkSend Accept Into Pool if (strCommand == "dsa") { //Darksend Accept Into Pool
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
std::string strError = _("Incompatible version."); std::string strError = _("Incompatible version.");
@ -61,8 +61,8 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
} }
if(!fMasterNode){ if(!fMasterNode){
std::string strError = _("This is not a masternode."); std::string strError = _("This is not a Masternode.");
LogPrintf("dsa -- not a masternode! \n"); LogPrintf("dsa -- not a Masternode! \n");
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, strError); pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, strError);
return; return;
@ -76,7 +76,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
CMasternode* pmn = mnodeman.Find(activeMasternode.vin); CMasternode* pmn = mnodeman.Find(activeMasternode.vin);
if(pmn == NULL) if(pmn == NULL)
{ {
std::string strError = _("Not in the masternode list."); std::string strError = _("Not in the Masternode list.");
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, strError); pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, strError);
return; return;
} }
@ -102,7 +102,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
return; return;
} }
} else if (strCommand == "dsq") { //DarkSend Queue } else if (strCommand == "dsq") { //Darksend Queue
LOCK(cs_darksend); LOCK(cs_darksend);
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
@ -125,7 +125,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
if(dsq.ready) { if(dsq.ready) {
if(!pSubmittedToMasternode) return; if(!pSubmittedToMasternode) return;
if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)addr){ if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)addr){
LogPrintf("dsq - message doesn't match current masternode - %s != %s\n", pSubmittedToMasternode->addr.ToString().c_str(), addr.ToString().c_str()); LogPrintf("dsq - message doesn't match current Masternode - %s != %s\n", pSubmittedToMasternode->addr.ToString().c_str(), addr.ToString().c_str());
return; return;
} }
@ -133,7 +133,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
//save the relay signature info //save the relay signature info
AddRelaySignature(dsq.vchRelaySig, dsq.nBlockHeight, dsq.strSharedKey); AddRelaySignature(dsq.vchRelaySig, dsq.nBlockHeight, dsq.strSharedKey);
if (fDebug) LogPrintf("darksend queue is ready - %s\n", addr.ToString().c_str()); if (fDebug) LogPrintf("Darksend queue is ready - %s\n", addr.ToString().c_str());
PrepareDarksendDenominate(); PrepareDarksendDenominate();
} }
} else { } else {
@ -145,22 +145,22 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
//don't allow a few nodes to dominate the queuing process //don't allow a few nodes to dominate the queuing process
if(pmn->nLastDsq != 0 && if(pmn->nLastDsq != 0 &&
pmn->nLastDsq + mnodeman.CountMasternodesAboveProtocol(MIN_POOL_PEER_PROTO_VERSION)/5 > nDsqCount){ pmn->nLastDsq + mnodeman.CountMasternodesAboveProtocol(MIN_POOL_PEER_PROTO_VERSION)/5 > nDsqCount){
if(fDebug) LogPrintf("dsq -- masternode sending too many dsq messages. %s \n", pmn->addr.ToString().c_str()); if(fDebug) LogPrintf("dsq -- Masternode sending too many dsq messages. %s \n", pmn->addr.ToString().c_str());
return; return;
} }
nDsqCount++; nDsqCount++;
pmn->nLastDsq = nDsqCount; pmn->nLastDsq = nDsqCount;
pmn->allowFreeTx = true; pmn->allowFreeTx = true;
if(fDebug) LogPrintf("dsq - new darksend queue object - %s\n", addr.ToString().c_str()); if(fDebug) LogPrintf("dsq - new Darksend queue object - %s\n", addr.ToString().c_str());
vecDarksendQueue.push_back(dsq); vecDarksendQueue.push_back(dsq);
dsq.Relay(); dsq.Relay();
dsq.time = GetTime(); dsq.time = GetTime();
} }
} else if (strCommand == "dsr") { //DarkSend Relay } else if (strCommand == "dsr") { //Darksend Relay
//* Ask a masternode to relay an anonymous output to another masternode *// //* Ask a Masternode to relay an anonymous output to another Masternode *//
std::string error = ""; std::string error = "";
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
@ -169,7 +169,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
} }
if(!fMasterNode){ if(!fMasterNode){
LogPrintf("dsr -- not a masternode! \n"); LogPrintf("dsr -- not a Masternode! \n");
return; return;
} }
@ -189,22 +189,22 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
CMasternode* pmn = mnodeman.Find(dsr.vinMasternode); CMasternode* pmn = mnodeman.Find(dsr.vinMasternode);
if(!pmn){ if(!pmn){
LogPrintf("dsr -- unknown masternode! %s \n", dsr.vinMasternode.ToString().c_str()); LogPrintf("dsr -- unknown Masternode! %s \n", dsr.vinMasternode.ToString().c_str());
return; return;
} }
int a = mnodeman.GetMasternodeRank(activeMasternode.vin, chainActive.Tip()->nHeight, MIN_POOL_PEER_PROTO_VERSION); int a = mnodeman.GetMasternodeRank(activeMasternode.vin, chainActive.Tip()->nHeight, MIN_POOL_PEER_PROTO_VERSION);
if(a > 20){ if(a > 20){
LogPrintf("dsr -- unknown/invalid masternode! %s \n", activeMasternode.vin.ToString().c_str()); LogPrintf("dsr -- unknown/invalid Masternode! %s \n", activeMasternode.vin.ToString().c_str());
return; return;
} }
//check the signature from the target masternode //check the signature from the target Masternode
std::string strMessage = boost::lexical_cast<std::string>(dsr.nBlockHeight); std::string strMessage = boost::lexical_cast<std::string>(dsr.nBlockHeight);
std::string errorMessage = ""; std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, dsr.vchSig, strMessage, errorMessage)){ if(!darkSendSigner.VerifyMessage(pmn->pubkey2, dsr.vchSig, strMessage, errorMessage)){
LogPrintf("dsr - Got bad masternode address signature\n"); LogPrintf("dsr - Got bad Masternode address signature\n");
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
return; return;
} }
@ -219,7 +219,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
} }
} }
} else if (strCommand == "dsai") { //DarkSend Anonymous Item (Input/Output/Sig) } else if (strCommand == "dsai") { //Darksend Anonymous Item (Input/Output/Sig)
std::string error = ""; std::string error = "";
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
@ -228,7 +228,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
} }
if(!fMasterNode){ if(!fMasterNode){
LogPrintf("dsai -- not a masternode! \n"); LogPrintf("dsai -- not a Masternode! \n");
return; return;
} }
@ -246,15 +246,15 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
CMasternode* pmn = mnodeman.Find(dsr.vinMasternode); CMasternode* pmn = mnodeman.Find(dsr.vinMasternode);
if(!pmn){ if(!pmn){
LogPrintf("dsr -- unknown masternode! %s \n", dsr.vinMasternode.ToString().c_str()); LogPrintf("dsr -- unknown Masternode! %s \n", dsr.vinMasternode.ToString().c_str());
return; return;
} }
//check the signature from the target masternode //check the signature from the target Masternode
std::string strMessage = boost::lexical_cast<std::string>(dsr.nBlockHeight); std::string strMessage = boost::lexical_cast<std::string>(dsr.nBlockHeight);
std::string errorMessage = ""; std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, dsr.vchSig, strMessage, errorMessage)){ if(!darkSendSigner.VerifyMessage(pmn->pubkey2, dsr.vchSig, strMessage, errorMessage)){
LogPrintf("dsr - Got bad masternode address signature\n"); LogPrintf("dsr - Got bad Masternode address signature\n");
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
return; return;
} }
@ -287,7 +287,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
RelayStatus(sessionID, GetState(), GetEntriesCount(), MASTERNODE_ACCEPTED); RelayStatus(sessionID, GetState(), GetEntriesCount(), MASTERNODE_ACCEPTED);
Check(); Check();
} else if (strCommand == "dsi") { //DarkSend vIn } else if (strCommand == "dsi") { //Darksend vIn
std::string error = ""; std::string error = "";
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
@ -299,8 +299,8 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
} }
if(!fMasterNode){ if(!fMasterNode){
LogPrintf("dsi -- not a masternode! \n"); LogPrintf("dsi -- not a Masternode! \n");
error = _("This is not a masternode ."); error = _("This is not a Masternode.");
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, error); pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, error);
return; return;
@ -373,7 +373,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
} }
if (nValueIn > DARKSEND_POOL_MAX) { if (nValueIn > DARKSEND_POOL_MAX) {
LogPrintf("dsi -- more than darksend pool max! %s\n", tx.ToString().c_str()); LogPrintf("dsi -- more than Darksend pool max! %s\n", tx.ToString().c_str());
error = _("Value more than Darksend pool maximum allows."); error = _("Value more than Darksend pool maximum allows.");
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, error); pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, error);
return; return;
@ -410,7 +410,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, error); pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, error);
} }
} else if (strCommand == "dssu") { //DarkSend status update } else if (strCommand == "dssu") { //Darksend status update
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
return; return;
@ -418,7 +418,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
if(!pSubmittedToMasternode) return; if(!pSubmittedToMasternode) return;
if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)pfrom->addr){ if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)pfrom->addr){
//LogPrintf("dssu - message doesn't match current masternode - %s != %s\n", pSubmittedToMasternode->addr.ToString().c_str(), pfrom->addr.ToString().c_str()); //LogPrintf("dssu - message doesn't match current Masternode - %s != %s\n", pSubmittedToMasternode->addr.ToString().c_str(), pfrom->addr.ToString().c_str());
return; return;
} }
@ -432,13 +432,13 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
if(fDebug) LogPrintf("dssu - state: %i entriesCount: %i accepted: %i error: %s \n", state, entriesCount, accepted, error.c_str()); if(fDebug) LogPrintf("dssu - state: %i entriesCount: %i accepted: %i error: %s \n", state, entriesCount, accepted, error.c_str());
if((accepted != 1 && accepted != 0) && sessionID != sessionIDMessage){ if((accepted != 1 && accepted != 0) && sessionID != sessionIDMessage){
LogPrintf("dssu - message doesn't match current darksend session %d %d\n", sessionID, sessionIDMessage); LogPrintf("dssu - message doesn't match current Darksend session %d %d\n", sessionID, sessionIDMessage);
return; return;
} }
StatusUpdate(state, entriesCount, accepted, error, sessionIDMessage); StatusUpdate(state, entriesCount, accepted, error, sessionIDMessage);
} else if (strCommand == "dss") { //DarkSend Sign Final Tx } else if (strCommand == "dss") { //Darksend Sign Final Tx
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
return; return;
@ -463,14 +463,14 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
CheckFinalTransaction(); CheckFinalTransaction();
RelayStatus(sessionID, GetState(), GetEntriesCount(), MASTERNODE_RESET); RelayStatus(sessionID, GetState(), GetEntriesCount(), MASTERNODE_RESET);
} }
} else if (strCommand == "dsf") { //DarkSend Final tx } else if (strCommand == "dsf") { //Darksend Final tx
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
return; return;
} }
if(!pSubmittedToMasternode) return; if(!pSubmittedToMasternode) return;
if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)pfrom->addr){ if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)pfrom->addr){
//LogPrintf("dsc - message doesn't match current masternode - %s != %s\n", pSubmittedToMasternode->addr.ToString().c_str(), pfrom->addr.ToString().c_str()); //LogPrintf("dsc - message doesn't match current Masternode - %s != %s\n", pSubmittedToMasternode->addr.ToString().c_str(), pfrom->addr.ToString().c_str());
return; return;
} }
@ -479,14 +479,14 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
vRecv >> sessionIDMessage >> txNew; vRecv >> sessionIDMessage >> txNew;
if(sessionID != sessionIDMessage){ if(sessionID != sessionIDMessage){
if (fDebug) LogPrintf("dsf - message doesn't match current darksend session %d %d\n", sessionID, sessionIDMessage); if (fDebug) LogPrintf("dsf - message doesn't match current Darksend session %d %d\n", sessionID, sessionIDMessage);
return; return;
} }
//check to see if input is spent already? (and probably not confirmed) //check to see if input is spent already? (and probably not confirmed)
SignFinalTransaction(txNew, pfrom); SignFinalTransaction(txNew, pfrom);
} else if (strCommand == "dsc") { //DarkSend Complete } else if (strCommand == "dsc") { //Darksend Complete
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
return; return;
@ -494,7 +494,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
if(!pSubmittedToMasternode) return; if(!pSubmittedToMasternode) return;
if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)pfrom->addr){ if((CNetAddr)pSubmittedToMasternode->addr != (CNetAddr)pfrom->addr){
//LogPrintf("dsc - message doesn't match current masternode - %s != %s\n", pSubmittedToMasternode->addr.ToString().c_str(), pfrom->addr.ToString().c_str()); //LogPrintf("dsc - message doesn't match current Masternode - %s != %s\n", pSubmittedToMasternode->addr.ToString().c_str(), pfrom->addr.ToString().c_str());
return; return;
} }
@ -504,7 +504,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
vRecv >> sessionIDMessage >> error >> lastMessage; vRecv >> sessionIDMessage >> error >> lastMessage;
if(sessionID != sessionIDMessage){ if(sessionID != sessionIDMessage){
if (fDebug) LogPrintf("dsc - message doesn't match current darksend session %d %d\n", darkSendPool.sessionID, sessionIDMessage); if (fDebug) LogPrintf("dsc - message doesn't match current Darksend session %d %d\n", darkSendPool.sessionID, sessionIDMessage);
return; return;
} }
@ -515,7 +515,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
int randomizeList (int i) { return std::rand()%i;} int randomizeList (int i) { return std::rand()%i;}
// Recursively determine the rounds of a given input (How deep is the darksend chain for a given input) // Recursively determine the rounds of a given input (How deep is the Darksend chain for a given input)
int GetInputDarksendRounds(CTxIn in, int rounds) int GetInputDarksendRounds(CTxIn in, int rounds)
{ {
static std::map<uint256, CWalletTx> mDenomWtxes; static std::map<uint256, CWalletTx> mDenomWtxes;
@ -662,7 +662,7 @@ bool CDarksendPool::SetCollateralAddress(std::string strAddress){
CBitcoinAddress address; CBitcoinAddress address;
if (!address.SetString(strAddress)) if (!address.SetString(strAddress))
{ {
LogPrintf("CDarksendPool::SetCollateralAddress - Invalid DarkSend collateral address\n"); LogPrintf("CDarksendPool::SetCollateralAddress - Invalid Darksend collateral address\n");
return false; return false;
} }
collateralPubKey.SetDestination(address.Get()); collateralPubKey.SetDestination(address.Get());
@ -680,7 +680,7 @@ void CDarksendPool::UnlockCoins(){
} }
// //
// Check the Darksend progress and send client updates if a masternode // Check the Darksend progress and send client updates if a Masternode
// //
void CDarksendPool::Check() void CDarksendPool::Check()
{ {
@ -795,7 +795,7 @@ void CDarksendPool::CheckFinalTransaction()
if(!darkSendSigner.SetKey(strMasterNodePrivKey, strError, key2, pubkey2)) if(!darkSendSigner.SetKey(strMasterNodePrivKey, strError, key2, pubkey2))
{ {
LogPrintf("CDarksendPool::Check() - ERROR: Invalid masternodeprivkey: '%s'\n", strError.c_str()); LogPrintf("CDarksendPool::Check() - ERROR: Invalid Masternodeprivkey: '%s'\n", strError.c_str());
return; return;
} }
@ -843,12 +843,12 @@ void CDarksendPool::CheckFinalTransaction()
// Charge clients a fee if they're abusive // Charge clients a fee if they're abusive
// //
// Why bother? Darksend uses collateral to ensure abuse to the process is kept to a minimum. // Why bother? Darksend uses collateral to ensure abuse to the process is kept to a minimum.
// The submission and signing stages in darksend are completely separate. In the cases where // The submission and signing stages in Darksend are completely separate. In the cases where
// a client submits a transaction then refused to sign, there must be a cost. Otherwise they // a client submits a transaction then refused to sign, there must be a cost. Otherwise they
// would be able to do this over and over again and bring the mixing to a hault. // would be able to do this over and over again and bring the mixing to a hault.
// //
// How does this work? Messages to masternodes come in via "dsi", these require a valid collateral // How does this work? Messages to Masternodes come in via "dsi", these require a valid collateral
// transaction for the client to be able to enter the pool. This transaction is kept by the masternode // transaction for the client to be able to enter the pool. This transaction is kept by the Masternode
// until the transaction is either complete or fails. // until the transaction is either complete or fails.
// //
void CDarksendPool::ChargeFees(){ void CDarksendPool::ChargeFees(){
@ -965,7 +965,7 @@ void CDarksendPool::ChargeRandomFees(){
/* /*
Collateral Fee Charges: Collateral Fee Charges:
Being that DarkSend has "no fees" we need to have some kind of cost associated Being that Darksend has "no fees" we need to have some kind of cost associated
with using it to stop abuse. Otherwise it could serve as an attack vector and with using it to stop abuse. Otherwise it could serve as an attack vector and
allow endless transaction that would bloat Darkcoin and make it unusable. To allow endless transaction that would bloat Darkcoin and make it unusable. To
stop these kinds of attacks 1 in 10 successful transactions are charged. This stop these kinds of attacks 1 in 10 successful transactions are charged. This
@ -990,7 +990,7 @@ void CDarksendPool::ChargeRandomFees(){
} }
// //
// Check for various timeouts (queue objects, darksend, etc) // Check for various timeouts (queue objects, Darksend, etc)
// //
void CDarksendPool::CheckTimeout(){ void CDarksendPool::CheckTimeout(){
if(!fEnableDarksend && !fMasterNode) return; if(!fEnableDarksend && !fMasterNode) return;
@ -1003,7 +1003,7 @@ void CDarksendPool::CheckTimeout(){
} }
} }
// check darksend queue objects for timeouts // check Darksend queue objects for timeouts
int c = 0; int c = 0;
vector<CDarksendQueue>::iterator it; vector<CDarksendQueue>::iterator it;
for(it=vecDarksendQueue.begin();it<vecDarksendQueue.end();it++){ for(it=vecDarksendQueue.begin();it<vecDarksendQueue.end();it++){
@ -1021,7 +1021,7 @@ void CDarksendPool::CheckTimeout(){
if(state == POOL_STATUS_ACCEPTING_ENTRIES || state == POOL_STATUS_QUEUE){ if(state == POOL_STATUS_ACCEPTING_ENTRIES || state == POOL_STATUS_QUEUE){
c = 0; c = 0;
// if it's a masternode, the entries are stored in "entries", otherwise they're stored in myEntries // if it's a Masternode, the entries are stored in "entries", otherwise they're stored in myEntries
std::vector<CDarkSendEntry> *vec = &myEntries; std::vector<CDarkSendEntry> *vec = &myEntries;
if(fMasterNode) vec = &entries; if(fMasterNode) vec = &entries;
@ -1054,7 +1054,7 @@ void CDarksendPool::CheckTimeout(){
lastTimeChanged = GetTimeMillis(); lastTimeChanged = GetTimeMillis();
ChargeFees(); ChargeFees();
// reset session information for the queue query stage (before entering a masternode, clients will send a queue request to make sure they're compatible denomination wise) // reset session information for the queue query stage (before entering a Masternode, clients will send a queue request to make sure they're compatible denomination wise)
sessionUsers = 0; sessionUsers = 0;
sessionDenom = 0; sessionDenom = 0;
sessionFoundMasternode = false; sessionFoundMasternode = false;
@ -1301,7 +1301,7 @@ bool CDarksendPool::AddScriptSig(const CTxIn& newVin){
return false; return false;
} }
// check to make sure everything is signed // Check to make sure everything is signed
bool CDarksendPool::SignaturesComplete(){ bool CDarksendPool::SignaturesComplete(){
bool fFoundIncomplete = false; bool fFoundIncomplete = false;
BOOST_FOREACH(CTxDSIn in, anonTx.vin){ BOOST_FOREACH(CTxDSIn in, anonTx.vin){
@ -1319,7 +1319,7 @@ bool CDarksendPool::SignaturesComplete(){
} }
// //
// Execute a darksend denomination via a masternode. // Execute a Darksend denomination via a Masternode.
// This is only ran from clients // This is only ran from clients
// //
void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout, int64_t amount){ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout, int64_t amount){
@ -1339,9 +1339,9 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
// LogPrintf(" vout - %s\n", o.ToString().c_str()); // LogPrintf(" vout - %s\n", o.ToString().c_str());
// we should already be connected to a masternode // we should already be connected to a Masternode
if(!sessionFoundMasternode){ if(!sessionFoundMasternode){
LogPrintf("CDarksendPool::SendDarksendDenominate() - No masternode has been selected yet.\n"); LogPrintf("CDarksendPool::SendDarksendDenominate() - No Masternode has been selected yet.\n");
UnlockCoins(); UnlockCoins();
SetNull(true); SetNull(true);
return; return;
@ -1351,7 +1351,7 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
return; return;
if(fMasterNode) { if(fMasterNode) {
LogPrintf("CDarksendPool::SendDarksendDenominate() - DarkSend from a masternode is not supported currently.\n"); LogPrintf("CDarksendPool::SendDarksendDenominate() - Darksend from a Masternode is not supported currently.\n");
return; return;
} }
@ -1398,7 +1398,7 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
Check(); Check();
} }
// Incoming message from masternode updating the progress of darksend // Incoming message from Masternode updating the progress of Darksend
// newAccepted: -1 mean's it'n not a "transaction accepted/not accepted" message, just a standard update // newAccepted: -1 mean's it'n not a "transaction accepted/not accepted" message, just a standard update
// 0 means transaction was not accepted // 0 means transaction was not accepted
// 1 means transaction was accepted // 1 means transaction was accepted
@ -1435,10 +1435,10 @@ bool CDarksendPool::StatusUpdate(int newState, int newEntriesCount, int newAccep
UpdateState(POOL_STATUS_QUEUE); UpdateState(POOL_STATUS_QUEUE);
printf("Updated 1\n"); printf("Updated 1\n");
} else if (newAccepted == 0 && sessionID == 0 && !sessionFoundMasternode) { } else if (newAccepted == 0 && sessionID == 0 && !sessionFoundMasternode) {
LogPrintf("CDarksendPool::StatusUpdate - entry not accepted by masternode \n"); LogPrintf("CDarksendPool::StatusUpdate - entry not accepted by Masternode \n");
UnlockCoins(); UnlockCoins();
UpdateState(POOL_STATUS_ACCEPTING_ENTRIES); UpdateState(POOL_STATUS_ACCEPTING_ENTRIES);
DoAutomaticDenominating(); //try another masternode DoAutomaticDenominating(); //try another Masternode
} }
if(sessionFoundMasternode) return true; if(sessionFoundMasternode) return true;
} }
@ -1447,7 +1447,7 @@ bool CDarksendPool::StatusUpdate(int newState, int newEntriesCount, int newAccep
} }
// //
// After we receive the finalized transaction from the masternode, we must // After we receive the finalized transaction from the Masternode, we must
// check it to make sure it's what we want, then sign it if we agree. // check it to make sure it's what we want, then sign it if we agree.
// If we refuse to sign, it's possible we'll be charged collateral // If we refuse to sign, it's possible we'll be charged collateral
// //
@ -1519,7 +1519,7 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
if(!fSubmitAnonymousFailed){ if(!fSubmitAnonymousFailed){
RelaySignaturesAnon(sigs); RelaySignaturesAnon(sigs);
} else { } else {
// push all of our signatures to the masternode // push all of our signatures to the Masternode
if(sigs.size() > 0 && node != NULL) if(sigs.size() > 0 && node != NULL)
node->PushMessage("dss", sigs); node->PushMessage("dss", sigs);
} }
@ -1545,7 +1545,7 @@ void CDarksendPool::NewBlock()
} }
} }
// Darksend transaction was completed (failed or successed) // Darksend transaction was completed (failed or successful)
void CDarksendPool::CompletedTransaction(bool error, std::string lastMessageNew) void CDarksendPool::CompletedTransaction(bool error, std::string lastMessageNew)
{ {
if(fMasterNode) return; if(fMasterNode) return;
@ -1591,8 +1591,8 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
if(state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) return false; if(state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) return false;
if(chainActive.Tip()->nHeight - cachedLastSuccess < minBlockSpacing) { if(chainActive.Tip()->nHeight - cachedLastSuccess < minBlockSpacing) {
LogPrintf("CDarksendPool::DoAutomaticDenominating - Last successful darksend action was too recent\n"); LogPrintf("CDarksendPool::DoAutomaticDenominating - Last successful Darksend action was too recent\n");
strAutoDenomResult = _("Last successful darksend action was too recent."); strAutoDenomResult = _("Last successful Darksend action was too recent.");
return false; return false;
} }
if(!fEnableDarksend) { if(!fEnableDarksend) {
@ -1613,8 +1613,8 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
} }
if(mnodeman.size() == 0){ if(mnodeman.size() == 0){
if(fDebug) LogPrintf("CDarksendPool::DoAutomaticDenominating - No masternodes detected\n"); if(fDebug) LogPrintf("CDarksendPool::DoAutomaticDenominating - No Masternodes detected\n");
strAutoDenomResult = _("No masternodes detected."); strAutoDenomResult = _("No Masternodes detected.");
return false; return false;
} }
@ -1678,7 +1678,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
std::vector<CTxOut> vOut; std::vector<CTxOut> vOut;
// initial phase, find a masternode // initial phase, find a Masternode
if(!sessionFoundMasternode){ if(!sessionFoundMasternode){
int nUseQueue = rand()%100; int nUseQueue = rand()%100;
@ -1714,7 +1714,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
//non-denom's are incompatible //non-denom's are incompatible
if((dsq.nDenom & (1 << 4))) continue; if((dsq.nDenom & (1 << 4))) continue;
//don't reuse masternodes //don't reuse Masternodes
BOOST_FOREACH(CTxIn usedVin, vecMasternodesUsed){ BOOST_FOREACH(CTxIn usedVin, vecMasternodesUsed){
if(dsq.vin == usedVin) { if(dsq.vin == usedVin) {
continue; continue;
@ -1727,7 +1727,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
continue; continue;
} }
// connect to masternode and submit the queue request // connect to Masternode and submit the queue request
if(ConnectNode((CAddress)addr, NULL, true)){ if(ConnectNode((CAddress)addr, NULL, true)){
CNode* pNode = FindNode(addr); CNode* pNode = FindNode(addr);
if(pNode) if(pNode)
@ -1751,7 +1751,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
} }
} else { } else {
LogPrintf("DoAutomaticDenominating --- error connecting \n"); LogPrintf("DoAutomaticDenominating --- error connecting \n");
strAutoDenomResult = _("Error connecting to masternode."); strAutoDenomResult = _("Error connecting to Masternode.");
return DoAutomaticDenominating(); return DoAutomaticDenominating();
} }
@ -1767,10 +1767,10 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
CMasternode* pmn = mnodeman.FindRandom(); CMasternode* pmn = mnodeman.FindRandom();
if(pmn == NULL) if(pmn == NULL)
{ {
LogPrintf("DoAutomaticDenominating --- masternode list is empty!\n"); LogPrintf("DoAutomaticDenominating --- Masternode list is empty!\n");
return false; return false;
} }
//don't reuse masternodes //don't reuse Masternodes
BOOST_FOREACH(CTxIn usedVin, vecMasternodesUsed) { BOOST_FOREACH(CTxIn usedVin, vecMasternodesUsed) {
if(pmn->vin == usedVin){ if(pmn->vin == usedVin){
i++; i++;
@ -1789,7 +1789,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
} }
lastTimeChanged = GetTimeMillis(); lastTimeChanged = GetTimeMillis();
LogPrintf("DoAutomaticDenominating -- attempt %d connection to masternode %s\n", i, pmn->addr.ToString().c_str()); LogPrintf("DoAutomaticDenominating -- attempt %d connection to Masternode %s\n", i, pmn->addr.ToString().c_str());
if(ConnectNode((CAddress)pmn->addr, NULL, true)){ if(ConnectNode((CAddress)pmn->addr, NULL, true)){
LOCK(cs_vNodes); LOCK(cs_vNodes);
@ -1823,7 +1823,7 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
} }
} }
strAutoDenomResult = _("No compatible masternode found."); strAutoDenomResult = _("No compatible Masternode found.");
return false; return false;
} }
@ -1840,7 +1840,7 @@ bool CDarksendPool::PrepareDarksendDenominate()
{ {
// Submit transaction to the pool if we get here, use sessionDenom so we use the same amount of money // Submit transaction to the pool if we get here, use sessionDenom so we use the same amount of money
std::string strError = pwalletMain->PrepareDarksendDenominate(0, nDarksendRounds); std::string strError = pwalletMain->PrepareDarksendDenominate(0, nDarksendRounds);
LogPrintf("DoAutomaticDenominating : Running darksend denominate. Return '%s'\n", strError.c_str()); LogPrintf("DoAutomaticDenominating : Running Darksend denominate. Return '%s'\n", strError.c_str());
if(strError == "") return true; if(strError == "") return true;
@ -2303,7 +2303,7 @@ bool CDarksendQueue::Sign()
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, key2, pubkey2)) if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, key2, pubkey2))
{ {
LogPrintf("CDarksendQueue():Relay - ERROR: Invalid masternodeprivkey: '%s'\n", errorMessage.c_str()); LogPrintf("CDarksendQueue():Relay - ERROR: Invalid Masternodeprivkey: '%s'\n", errorMessage.c_str());
return false; return false;
} }
@ -2362,7 +2362,7 @@ bool CDarksendQueue::CheckSignature()
std::string errorMessage = ""; std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)){ if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)){
return error("CDarksendQueue::CheckSignature() - Got bad masternode address signature %s \n", vin.ToString().c_str()); return error("CDarksendQueue::CheckSignature() - Got bad Masternode address signature %s \n", vin.ToString().c_str());
} }
// -- second signature, for proving access to the anonymous relay system // -- second signature, for proving access to the anonymous relay system
@ -2495,7 +2495,7 @@ bool CDSAnonTx::AddSig(const CTxIn newIn){
//TODO: Rename/move to core //TODO: Rename/move to core
void ThreadCheckDarkSendPool() void ThreadCheckDarkSendPool()
{ {
if(fLiteMode) return; //disable all darksend/masternode related functionality if(fLiteMode) return; //disable all Darksend/Masternode related functionality
// Make this thread recognisable as the wallet flushing thread // Make this thread recognisable as the wallet flushing thread
RenameThread("darkcoin-darksend"); RenameThread("darkcoin-darksend");
@ -2532,7 +2532,7 @@ void ThreadCheckDarkSendPool()
if(c % MASTERNODES_DUMP_SECONDS == 0) DumpMasternodes(); if(c % MASTERNODES_DUMP_SECONDS == 0) DumpMasternodes();
//try to sync the masternode list and payment list every 5 seconds from at least 3 nodes //try to sync the Masternode list and payment list every 5 seconds from at least 3 nodes
if(c % 5 == 0 && RequestedMasterNodeList < 3){ if(c % 5 == 0 && RequestedMasterNodeList < 3){
bool fIsInitialDownload = IsInitialBlockDownload(); bool fIsInitialDownload = IsInitialBlockDownload();
if(!fIsInitialDownload) { if(!fIsInitialDownload) {
@ -2547,7 +2547,7 @@ void ThreadCheckDarkSendPool()
LogPrintf("Successfully synced, asking for Masternode list and payment list\n"); LogPrintf("Successfully synced, asking for Masternode list and payment list\n");
//request full mn list only if masternodes.dat was updated quite a long time ago //request full mn list only if Masternodes.dat was updated quite a long time ago
mnodeman.DsegUpdate(pnode); mnodeman.DsegUpdate(pnode);
pnode->PushMessage("mnget"); //sync payees pnode->PushMessage("mnget"); //sync payees
@ -2559,7 +2559,7 @@ void ThreadCheckDarkSendPool()
} }
if(c % 60 == 0){ if(c % 60 == 0){
//if we've used 1/5 of the masternode list, then clear the list. //if we've used 1/5 of the Masternode list, then clear the list.
if((int)vecMasternodesUsed.size() > (int)mnodeman.size() / 5) if((int)vecMasternodesUsed.size() > (int)mnodeman.size() / 5)
vecMasternodesUsed.clear(); vecMasternodesUsed.clear();
} }

View File

@ -38,9 +38,9 @@ class CActiveMasternode;
#define MASTERNODE_REJECTED 0 #define MASTERNODE_REJECTED 0
#define MASTERNODE_RESET -1 #define MASTERNODE_RESET -1
#define DARKSEND_QUEUE_TIMEOUT 120 #define DARKSEND_QUEUE_TIMEOUT 120 // in seconds
#define DARKSEND_SIGNING_TIMEOUT 30 #define DARKSEND_SIGNING_TIMEOUT 30 // in seconds
#define DARKSEND_DOWNGRADE_TIMEOUT 30 #define DARKSEND_DOWNGRADE_TIMEOUT 30 // in seconds
// used for anonymous relaying of inputs/outputs/sigs // used for anonymous relaying of inputs/outputs/sigs
#define DARKSEND_RELAY_IN 1 #define DARKSEND_RELAY_IN 1
@ -54,13 +54,11 @@ extern std::string strMasterNodePrivKey;
extern map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes; extern map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes;
extern CActiveMasternode activeMasternode; extern CActiveMasternode activeMasternode;
// get the darksend chain depth for a given input // get the Darksend chain depth for a given input
int GetInputDarksendRounds(CTxIn in, int rounds=0); int GetInputDarksendRounds(CTxIn in, int rounds=0);
// /** Holds an Darksend input
// Holds an Darksend input */
//
class CTxDSIn : public CTxIn class CTxDSIn : public CTxIn
{ {
public: public:
@ -76,8 +74,9 @@ public:
}; };
// A clients transaction in the darksend pool /** A clients transaction in the Darksend pool
// -- holds the input/output mapping for each user in the pool * -- holds the input/output mapping for each user in the pool
*/
class CDarkSendEntry class CDarkSendEntry
{ {
public: public:
@ -96,6 +95,7 @@ public:
amount = 0; amount = 0;
} }
/// Add entries to use for Darksend
bool Add(const std::vector<CTxIn> vinIn, int64_t amountIn, const CTransaction collateralIn, const std::vector<CTxOut> voutIn) bool Add(const std::vector<CTxIn> vinIn, int64_t amountIn, const CTransaction collateralIn, const std::vector<CTxOut> voutIn)
{ {
if(isSet){return false;} if(isSet){return false;}
@ -110,6 +110,7 @@ public:
return true; return true;
} }
/// Is this Darksend expired?
bool IsExpired() bool IsExpired()
{ {
return (GetTime() - addedTime) > DARKSEND_QUEUE_TIMEOUT;// 120 seconds return (GetTime() - addedTime) > DARKSEND_QUEUE_TIMEOUT;// 120 seconds
@ -117,9 +118,9 @@ public:
}; };
// /**
// A currently inprogress darksend merge and denomination information * A currently inprogress Darksend merge and denomination information
// */
class CDarksendQueue class CDarksendQueue
{ {
public: public:
@ -184,19 +185,31 @@ public:
} }
void SetSharedKey(std::string strSharedKey); void SetSharedKey(std::string strSharedKey);
/** Sign this Darksend transaction
* \return true if all conditions are met:
* 1) we have an active Masternode,
* 2) we have a valid Masternode private key,
* 3) we signed the message successfully, and
* 4) we verified the message successfully
*/
bool Sign(); bool Sign();
bool Relay(); bool Relay();
/// Is this Darksend expired?
bool IsExpired() bool IsExpired()
{ {
return (GetTime() - time) > DARKSEND_QUEUE_TIMEOUT;// 120 seconds return (GetTime() - time) > DARKSEND_QUEUE_TIMEOUT;// 120 seconds
} }
/// Check if we have a valid Masternode address
bool CheckSignature(); bool CheckSignature();
}; };
// store darksend tx signature information /** Helper class to store Darksend transaction (tx) information.
*/
class CDarksendBroadcastTx class CDarksendBroadcastTx
{ {
public: public:
@ -206,9 +219,8 @@ public:
int64_t sigTime; int64_t sigTime;
}; };
// /** Helper object for signing and checking signatures
// Helper object for signing and checking signatures */
//
class CDarkSendSigner class CDarkSendSigner
{ {
public: public:
@ -218,9 +230,8 @@ public:
bool VerifyMessage(CPubKey pubkey, std::vector<unsigned char>& vchSig, std::string strMessage, std::string& errorMessage); bool VerifyMessage(CPubKey pubkey, std::vector<unsigned char>& vchSig, std::string strMessage, std::string& errorMessage);
}; };
// /** Build a transaction anonymously
// Build a transaction anonymously */
//
class CDSAnonTx class CDSAnonTx
{ {
public: public:
@ -230,6 +241,8 @@ public:
bool IsTransactionValid(); bool IsTransactionValid();
bool AddOutput(const CTxOut out); bool AddOutput(const CTxOut out);
bool AddInput(const CTxIn in); bool AddInput(const CTxIn in);
/// Add Signature
bool AddSig(const CTxIn in); bool AddSig(const CTxIn in);
int CountEntries() {return (int)vin.size() + (int)vout.size();} int CountEntries() {return (int)vin.size() + (int)vout.size();}
}; };
@ -237,16 +250,15 @@ public:
void ConnectToDarkSendMasterNodeWinner(); void ConnectToDarkSendMasterNodeWinner();
// /** Used to keep track of current status of Darksend pool
// Used to keep track of current status of darksend pool */
//
class CDarksendPool class CDarksendPool
{ {
public: public:
// clients entries // clients entries
std::vector<CDarkSendEntry> myEntries; std::vector<CDarkSendEntry> myEntries;
// masternode entries // Masternode entries
std::vector<CDarkSendEntry> entries; std::vector<CDarkSendEntry> entries;
// the finalized transaction ready for signing // the finalized transaction ready for signing
CTransaction finalTransaction; CTransaction finalTransaction;
@ -255,8 +267,8 @@ public:
bool fSubmitAnonymousFailed; bool fSubmitAnonymousFailed;
int nCountAttempts; int nCountAttempts;
int64_t lastTimeChanged; int64_t lastTimeChanged; // time in UTC milliseconds
int64_t lastAutoDenomination; int64_t lastAutoDenomination; // Note: possibly not used TODO: Delete?
unsigned int state; unsigned int state;
unsigned int entriesCount; unsigned int entriesCount;
@ -278,7 +290,7 @@ public:
int sessionID; int sessionID;
int sessionDenom; //Users must submit an denom matching this int sessionDenom; //Users must submit an denom matching this
int sessionUsers; //N Users have said they'll join int sessionUsers; //N Users have said they'll join
bool sessionFoundMasternode; //If we've found a compatible masternode bool sessionFoundMasternode; //If we've found a compatible Masternode
int64_t sessionTotalValue; //used for autoDenom int64_t sessionTotalValue; //used for autoDenom
std::vector<CTransaction> vecSessionCollateral; std::vector<CTransaction> vecSessionCollateral;
@ -303,7 +315,7 @@ public:
CDarksendPool() CDarksendPool()
{ {
/* DarkSend uses collateral addresses to trust parties entering the pool /* Darksend uses collateral addresses to trust parties entering the pool
to behave themselves. If they don't it takes their money. */ to behave themselves. If they don't it takes their money. */
cachedLastSuccess = 0; cachedLastSuccess = 0;
@ -319,7 +331,21 @@ public:
SetNull(); SetNull();
} }
//specific messages for the Darksend protocol /** Process a Darksend message using the Darksend protocol
* \param pfrom
* \param strCommand lower case command string; valid values are:
* Command | Description
* -------- | -----------------
* dsa | Darksend Acceptable
* dsc | Darksend Complete
* dsf | Darksend Final tx
* dsi | Darksend vIn
* dsq | Darksend Queue
* dss | Darksend Signal Final Tx
* dssu | Darksend status update
* dssub | Darksend Subscribe To
* \param vRecv
*/
void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void InitCollateralAddress(){ void InitCollateralAddress(){
@ -382,7 +408,7 @@ public:
void UpdateState(unsigned int newState) void UpdateState(unsigned int newState)
{ {
if (fMasterNode && (newState == POOL_STATUS_ERROR || newState == POOL_STATUS_SUCCESS)){ if (fMasterNode && (newState == POOL_STATUS_ERROR || newState == POOL_STATUS_SUCCESS)){
LogPrintf("CDarksendPool::UpdateState() - Can't set state to ERROR or SUCCESS as a masternode. \n"); LogPrintf("CDarksendPool::UpdateState() - Can't set state to ERROR or SUCCESS as a Masternode. \n");
return; return;
} }
@ -405,38 +431,38 @@ public:
return POOL_MAX_TRANSACTIONS; return POOL_MAX_TRANSACTIONS;
} }
//Do we have enough users to take entries? /// Do we have enough users to take entries?
bool IsSessionReady(){ bool IsSessionReady(){
return sessionUsers >= GetMaxPoolTransactions(); return sessionUsers >= GetMaxPoolTransactions();
} }
// Are these outputs compatible with other client in the pool? /// Are these outputs compatible with other client in the pool?
bool IsCompatibleWithEntries(std::vector<CTxOut>& vout); bool IsCompatibleWithEntries(std::vector<CTxOut>& vout);
// Is this amount compatible with other client in the pool? /// Is this amount compatible with other client in the pool?
bool IsCompatibleWithSession(int64_t nAmount, CTransaction txCollateral, std::string& strReason); bool IsCompatibleWithSession(int64_t nAmount, CTransaction txCollateral, std::string& strReason);
// Passively run Darksend in the background according to the configuration in settings (only for QT) /// Passively run Darksend in the background according to the configuration in settings (only for QT)
bool DoAutomaticDenominating(bool fDryRun=false, bool ready=false); bool DoAutomaticDenominating(bool fDryRun=false, bool ready=false);
bool PrepareDarksendDenominate(); bool PrepareDarksendDenominate();
// check for process in Darksend /// Check for process in Darksend
void Check(); void Check();
void CheckFinalTransaction(); void CheckFinalTransaction();
// charge fees to bad actors /// Charge fees to bad actors (Charge clients a fee if they're abusive)
void ChargeFees(); void ChargeFees();
// rarely charge fees to pay miners /// Rarely charge fees to pay miners
void ChargeRandomFees(); void ChargeRandomFees();
void CheckTimeout(); void CheckTimeout();
void CheckForCompleteQueue(); void CheckForCompleteQueue();
// check to make sure a signature matches an input in the pool /// Check to make sure a signature matches an input in the pool
bool SignatureValid(const CScript& newSig, const CTxIn& newVin); bool SignatureValid(const CScript& newSig, const CTxIn& newVin);
// if the collateral is valid given by a client /// If the collateral is valid given by a client
bool IsCollateralValid(const CTransaction& txCollateral); bool IsCollateralValid(const CTransaction& txCollateral);
// add a clients entry to the pool /// Add a clients entry to the pool
bool AddEntry(const std::vector<CTxIn>& newInput, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& newOutput, std::string& error); bool AddEntry(const std::vector<CTxIn>& newInput, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& newOutput, std::string& error);
// add an anonymous output/inputs/sig /// Add an anonymous output/inputs/sig
bool AddAnonymousOutput(const CTxOut& out) {return anonTx.AddOutput(out);} bool AddAnonymousOutput(const CTxOut& out) {return anonTx.AddOutput(out);}
bool AddAnonymousInput(const CTxIn& in) {return anonTx.AddInput(in);} bool AddAnonymousInput(const CTxIn& in) {return anonTx.AddInput(in);}
bool AddAnonymousSig(const CTxIn& in) {return anonTx.AddSig(in);} bool AddAnonymousSig(const CTxIn& in) {return anonTx.AddSig(in);}
@ -447,36 +473,36 @@ public:
return true; return true;
} }
// add signature to a vin /// Add signature to a vin
bool AddScriptSig(const CTxIn& newVin); bool AddScriptSig(const CTxIn& newVin);
// are all inputs signed? /// Check that all inputs are signed. (Are all inputs signed?)
bool SignaturesComplete(); bool SignaturesComplete();
// as a client, send a transaction to a masternode to start the denomination process /// As a client, send a transaction to a Masternode to start the denomination process
void SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout, int64_t amount); void SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout, int64_t amount);
// get masternode updates about the progress of darksend /// Get Masternode updates about the progress of Darksend
bool StatusUpdate(int newState, int newEntriesCount, int newAccepted, std::string& error, int newSessionID=0); bool StatusUpdate(int newState, int newEntriesCount, int newAccepted, std::string& error, int newSessionID=0);
// as a client, check and sign the final transaction /// As a client, check and sign the final transaction
bool SignFinalTransaction(CTransaction& finalTransactionNew, CNode* node); bool SignFinalTransaction(CTransaction& finalTransactionNew, CNode* node);
// get the last valid block hash for a given modulus /// Get the last valid block hash for a given modulus
bool GetLastValidBlockHash(uint256& hash, int mod=1, int nBlockHeight=0); bool GetLastValidBlockHash(uint256& hash, int mod=1, int nBlockHeight=0);
// process a new block /// Process a new block
void NewBlock(); void NewBlock();
void CompletedTransaction(bool error, std::string lastMessageNew); void CompletedTransaction(bool error, std::string lastMessageNew);
void ClearLastMessage(); void ClearLastMessage();
// used for liquidity providers /// Used for liquidity providers
bool SendRandomPaymentToSelf(); bool SendRandomPaymentToSelf();
// split up large inputs or make fee sized inputs /// Split up large inputs or make fee sized inputs
bool MakeCollateralAmounts(); bool MakeCollateralAmounts();
bool CreateDenominated(int64_t nTotalValue); bool CreateDenominated(int64_t nTotalValue);
// get the denominations for a list of outputs (returns a bitshifted integer) /// Get the denominations for a list of outputs (returns a bitshifted integer)
int GetDenominations(const std::vector<CTxOut>& vout); int GetDenominations(const std::vector<CTxOut>& vout);
void GetDenominationsToString(int nDenom, std::string& strDenom); void GetDenominationsToString(int nDenom, std::string& strDenom);
// get the denominations for a specific amount of darkcoin. /// Get the denominations for a specific amount of darkcoin.
int GetDenominationsByAmount(int64_t nAmount, int nDenomTarget=0); int GetDenominationsByAmount(int64_t nAmount, int nDenomTarget=0);
int GetDenominationsByAmounts(std::vector<int64_t>& vecAmount); int GetDenominationsByAmounts(std::vector<int64_t>& vecAmount);

View File

@ -12,7 +12,7 @@
/** Object for who's going to get paid on which blocks */ /** Object for who's going to get paid on which blocks */
CMasternodePayments masternodePayments; CMasternodePayments masternodePayments;
// keep track of masternode votes I've seen // keep track of Masternode votes I've seen
map<uint256, CMasternodePaymentWinner> mapSeenMasternodeVotes; map<uint256, CMasternodePaymentWinner> mapSeenMasternodeVotes;
// keep track of the scanning errors I've seen // keep track of the scanning errors I've seen
map<uint256, int> mapSeenMasternodeScanningErrors; map<uint256, int> mapSeenMasternodeScanningErrors;
@ -24,7 +24,7 @@ void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDa
if(IsInitialBlockDownload()) return; if(IsInitialBlockDownload()) return;
if (strCommand == "mnget") { //Masternode Payments Request Sync if (strCommand == "mnget") { //Masternode Payments Request Sync
if(fLiteMode) return; //disable all darksend/masternode related functionality if(fLiteMode) return; //disable all Darksend/Masternode related functionality
if(pfrom->HasFulfilledRequest("mnget")) { if(pfrom->HasFulfilledRequest("mnget")) {
LogPrintf("mnget - peer already asked me for the list\n"); LogPrintf("mnget - peer already asked me for the list\n");
@ -34,7 +34,7 @@ void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDa
pfrom->FulfilledRequest("mnget"); pfrom->FulfilledRequest("mnget");
masternodePayments.Sync(pfrom); masternodePayments.Sync(pfrom);
LogPrintf("mnget - Sent masternode winners to %s\n", pfrom->addr.ToString().c_str()); LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString().c_str());
} }
else if (strCommand == "mnw") { //Masternode Payments Declare Winner else if (strCommand == "mnw") { //Masternode Payments Declare Winner
//this is required in litemode //this is required in litemode
@ -185,7 +185,7 @@ CMasternode::CMasternode(CService newAddr, CTxIn newVin, CPubKey newPubkey, std:
} }
// //
// Deterministically calculate a given "score" for a masternode depending on how close it's hash is to // Deterministically calculate a given "score" for a Masternode depending on how close it's hash is to
// the proof of work for that block. The further away they are the better, the furthest will win the election // the proof of work for that block. The further away they are the better, the furthest will win the election
// and get paid this block // and get paid this block
// //
@ -263,7 +263,7 @@ bool CMasternodePayments::Sign(CMasternodePaymentWinner& winner)
if(!darkSendSigner.SetKey(strMasterPrivKey, errorMessage, key2, pubkey2)) if(!darkSendSigner.SetKey(strMasterPrivKey, errorMessage, key2, pubkey2))
{ {
LogPrintf("CMasternodePayments::Sign - ERROR: Invalid masternodeprivkey: '%s'\n", errorMessage.c_str()); LogPrintf("CMasternodePayments::Sign - ERROR: Invalid Masternodeprivkey: '%s'\n", errorMessage.c_str());
return false; return false;
} }
@ -362,7 +362,7 @@ void CMasternodePayments::CleanPaymentList()
vector<CMasternodePaymentWinner>::iterator it; vector<CMasternodePaymentWinner>::iterator it;
for(it=vWinning.begin();it<vWinning.end();it++){ for(it=vWinning.begin();it<vWinning.end();it++){
if(chainActive.Tip()->nHeight - (*it).nBlockHeight > nLimit){ if(chainActive.Tip()->nHeight - (*it).nBlockHeight > nLimit){
if(fDebug) LogPrintf("CMasternodePayments::CleanPaymentList - Removing old masternode payment - block %d\n", (*it).nBlockHeight); if(fDebug) LogPrintf("CMasternodePayments::CleanPaymentList - Removing old Masternode payment - block %d\n", (*it).nBlockHeight);
vWinning.erase(it); vWinning.erase(it);
break; break;
} }
@ -459,7 +459,7 @@ bool CMasternodePayments::SetPrivKey(std::string strPrivKey)
Sign(winner); Sign(winner);
if(CheckSignature(winner)){ if(CheckSignature(winner)){
LogPrintf("CMasternodePayments::SetPrivKey - Successfully initialized as masternode payments master\n"); LogPrintf("CMasternodePayments::SetPrivKey - Successfully initialized as Masternode payments master\n");
enabled = true; enabled = true;
return true; return true;
} else { } else {

View File

@ -53,7 +53,7 @@ enum masternodeState {
void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
// //
// The Masternode Class. For managing the darksend process. It contains the input of the 1000DRK, signature to prove // The Masternode Class. For managing the Darksend process. It contains the input of the 1000DRK, signature to prove
// it's the one who own that ip address and code for calculating the payment election. // it's the one who own that ip address and code for calculating the payment election.
// //
class CMasternode class CMasternode

View File

@ -140,7 +140,7 @@ bool CMasternodeMan::Add(CMasternode &mn)
if (pmn == NULL) if (pmn == NULL)
{ {
if(fDebug) LogPrintf("CMasternodeMan: Adding new masternode %s - %i now\n", mn.addr.ToString().c_str(), size() + 1); if(fDebug) LogPrintf("CMasternodeMan: Adding new Masternode %s - %i now\n", mn.addr.ToString().c_str(), size() + 1);
vMasternodes.push_back(mn); vMasternodes.push_back(mn);
return true; return true;
} }
@ -166,14 +166,14 @@ void CMasternodeMan::CheckAndRemove()
vector<CMasternode>::iterator it = vMasternodes.begin(); vector<CMasternode>::iterator it = vMasternodes.begin();
while(it != vMasternodes.end()){ while(it != vMasternodes.end()){
if((*it).activeState == 4 || (*it).activeState == 3){ if((*it).activeState == 4 || (*it).activeState == 3){
if(fDebug) LogPrintf("CMasternodeMan: Removing inactive masternode %s - %i now\n", (*it).addr.ToString().c_str(), size() - 1); if(fDebug) LogPrintf("CMasternodeMan: Removing inactive Masternode %s - %i now\n", (*it).addr.ToString().c_str(), size() - 1);
it = vMasternodes.erase(it); it = vMasternodes.erase(it);
} else { } else {
++it; ++it;
} }
} }
// check who's asked for the masternode list // check who's asked for the Masternode list
map<CNetAddr, int64_t>::iterator it1 = mAskedUsForMasternodeList.begin(); map<CNetAddr, int64_t>::iterator it1 = mAskedUsForMasternodeList.begin();
while(it1 != mAskedUsForMasternodeList.end()){ while(it1 != mAskedUsForMasternodeList.end()){
if((*it1).second < GetTime()) { if((*it1).second < GetTime()) {
@ -183,7 +183,7 @@ void CMasternodeMan::CheckAndRemove()
} }
} }
// check who we asked for the masternode list // check who we asked for the Masternode list
it1 = mWeAskedForMasternodeList.begin(); it1 = mWeAskedForMasternodeList.begin();
while(it1 != mWeAskedForMasternodeList.end()){ while(it1 != mWeAskedForMasternodeList.end()){
if((*it1).second < GetTime()){ if((*it1).second < GetTime()){
@ -193,7 +193,7 @@ void CMasternodeMan::CheckAndRemove()
} }
} }
// check which masternodes we've asked for // check which Masternodes we've asked for
map<COutPoint, int64_t>::iterator it2 = mWeAskedForMasternodeListEntry.begin(); map<COutPoint, int64_t>::iterator it2 = mWeAskedForMasternodeListEntry.begin();
while(it2 != mWeAskedForMasternodeListEntry.end()){ while(it2 != mWeAskedForMasternodeListEntry.end()){
if((*it2).second < GetTime()){ if((*it2).second < GetTime()){
@ -315,7 +315,7 @@ CMasternode* CMasternodeMan::GetCurrentMasterNode(int mod, int64_t nBlockHeight,
mn.Check(); mn.Check();
if(mn.protocolVersion < minProtocol || !mn.IsEnabled()) continue; if(mn.protocolVersion < minProtocol || !mn.IsEnabled()) continue;
// calculate the score for each masternode // calculate the score for each Masternode
uint256 n = mn.CalculateScore(mod, nBlockHeight); uint256 n = mn.CalculateScore(mod, nBlockHeight);
unsigned int n2 = 0; unsigned int n2 = 0;
memcpy(&n2, &n, sizeof(n2)); memcpy(&n2, &n, sizeof(n2));
@ -409,7 +409,7 @@ void CMasternodeMan::ProcessMasternodeConnections()
if(darkSendPool.pSubmittedToMasternode->addr == pnode->addr) continue; if(darkSendPool.pSubmittedToMasternode->addr == pnode->addr) continue;
if(pnode->fDarkSendMaster){ if(pnode->fDarkSendMaster){
LogPrintf("Closing masternode connection %s \n", pnode->addr.ToString().c_str()); LogPrintf("Closing Masternode connection %s \n", pnode->addr.ToString().c_str());
pnode->CloseSocketDisconnect(); pnode->CloseSocketDisconnect();
} }
} }
@ -432,7 +432,7 @@ void CMasternodeMan::RelayMasternodeEntryPing(const CTxIn vin, const std::vector
void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{ {
if(fLiteMode) return; //disable all darksend/masternode related functionality if(fLiteMode) return; //disable all Darksend/Masternode related functionality
if(IsInitialBlockDownload()) return; if(IsInitialBlockDownload()) return;
LOCK(cs); LOCK(cs);
@ -469,7 +469,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion); strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion);
if(protocolVersion < nMasternodeMinProtocol) { if(protocolVersion < nMasternodeMinProtocol) {
LogPrintf("dsee - ignoring outdated masternode %s protocol version %d\n", vin.ToString().c_str(), protocolVersion); LogPrintf("dsee - ignoring outdated Masternode %s protocol version %d\n", vin.ToString().c_str(), protocolVersion);
return; return;
} }
@ -493,7 +493,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
std::string errorMessage = ""; std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){ if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){
LogPrintf("dsee - Got bad masternode address signature\n"); LogPrintf("dsee - Got bad Masternode address signature\n");
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
return; return;
} }
@ -502,7 +502,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
if(addr.GetPort() != 9999) return; if(addr.GetPort() != 9999) return;
} }
//search existing masternode list, this is where we update existing masternodes with new dsee broadcasts //search existing Masternode list, this is where we update existing Masternodes with new dsee broadcasts
CMasternode* pmn = this->Find(vin); CMasternode* pmn = this->Find(vin);
if(pmn != NULL) if(pmn != NULL)
{ {
@ -529,15 +529,15 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
return; return;
} }
// make sure the vout that was signed is related to the transaction that spawned the masternode // make sure the vout that was signed is related to the transaction that spawned the Masternode
// - this is expensive, so it's only done once per masternode // - this is expensive, so it's only done once per Masternode
if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) { if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) {
LogPrintf("dsee - Got mismatched pubkey and vin\n"); LogPrintf("dsee - Got mismatched pubkey and vin\n");
Misbehaving(pfrom->GetId(), 100); Misbehaving(pfrom->GetId(), 100);
return; return;
} }
if(fDebug) LogPrintf("dsee - Got NEW masternode entry %s\n", addr.ToString().c_str()); if(fDebug) LogPrintf("dsee - Got NEW Masternode entry %s\n", addr.ToString().c_str());
// make sure it's still unspent // make sure it's still unspent
// - this is checked later by .check() in many places and by ThreadCheckDarkSendPool() // - this is checked later by .check() in many places and by ThreadCheckDarkSendPool()
@ -548,7 +548,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
tx.vin.push_back(vin); tx.vin.push_back(vin);
tx.vout.push_back(vout); tx.vout.push_back(vout);
if(AcceptableInputs(mempool, state, tx)){ if(AcceptableInputs(mempool, state, tx)){
if(fDebug) LogPrintf("dsee - Accepted masternode entry %i %i\n", count, current); if(fDebug) LogPrintf("dsee - Accepted Masternode entry %i %i\n", count, current);
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
LogPrintf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS); LogPrintf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS);
@ -567,7 +567,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS
if(pConfIndex->GetBlockTime() > sigTime) if(pConfIndex->GetBlockTime() > sigTime)
{ {
LogPrintf("dsee - Bad sigTime %d for masternode %20s %105s (%i conf block is at %d)\n", LogPrintf("dsee - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n",
sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime()); sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime());
return; return;
} }
@ -577,12 +577,12 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
// use this as a peer // use this as a peer
addrman.Add(CAddress(addr), pfrom->addr, 2*60*60); addrman.Add(CAddress(addr), pfrom->addr, 2*60*60);
// add our masternode // add our Masternode
CMasternode mn(addr, vin, pubkey, vchSig, sigTime, pubkey2, protocolVersion); CMasternode mn(addr, vin, pubkey, vchSig, sigTime, pubkey2, protocolVersion);
mn.UpdateLastSeen(lastUpdated); mn.UpdateLastSeen(lastUpdated);
this->Add(mn); this->Add(mn);
// if it matches our masternodeprivkey, then we've been remotely activated // if it matches our Masternode privkey, then we've been remotely activated
if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){ if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){
activeMasternode.EnableHotColdMasterNode(vin, addr); activeMasternode.EnableHotColdMasterNode(vin, addr);
} }
@ -591,7 +591,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
mnodeman.RelayMasternodeEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion); mnodeman.RelayMasternodeEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
} else { } else {
LogPrintf("dsee - Rejected masternode entry %s\n", addr.ToString().c_str()); LogPrintf("dsee - Rejected Masternode entry %s\n", addr.ToString().c_str());
int nDoS = 0; int nDoS = 0;
if (state.IsInvalid(nDoS)) if (state.IsInvalid(nDoS))
@ -624,7 +624,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
return; return;
} }
// see if we have this masternode // see if we have this Masternode
CMasternode* pmn = this->Find(vin); CMasternode* pmn = this->Find(vin);
if(pmn != NULL) if(pmn != NULL)
{ {
@ -637,7 +637,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
std::string errorMessage = ""; std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)) if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage))
{ {
LogPrintf("dseep - Got bad masternode address signature %s \n", vin.ToString().c_str()); LogPrintf("dseep - Got bad Masternode address signature %s \n", vin.ToString().c_str());
//Misbehaving(pfrom->GetId(), 100); //Misbehaving(pfrom->GetId(), 100);
return; return;
} }
@ -659,7 +659,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
return; return;
} }
if(fDebug) LogPrintf("dseep - Couldn't find masternode entry %s\n", vin.ToString().c_str()); if(fDebug) LogPrintf("dseep - Couldn't find Masternode entry %s\n", vin.ToString().c_str());
std::map<COutPoint, int64_t>::iterator i = mWeAskedForMasternodeListEntry.find(vin.prevout); std::map<COutPoint, int64_t>::iterator i = mWeAskedForMasternodeListEntry.find(vin.prevout);
if (i != mWeAskedForMasternodeListEntry.end()) if (i != mWeAskedForMasternodeListEntry.end())
@ -675,7 +675,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
int64_t askAgain = GetTime() + MASTERNODE_MIN_DSEEP_SECONDS; int64_t askAgain = GetTime() + MASTERNODE_MIN_DSEEP_SECONDS;
mWeAskedForMasternodeListEntry[vin.prevout] = askAgain; mWeAskedForMasternodeListEntry[vin.prevout] = askAgain;
} else if (strCommand == "dseg") { //Get masternode list or specific entry } else if (strCommand == "dseg") { //Get Masternode list or specific entry
CTxIn vin; CTxIn vin;
vRecv >> vin; vRecv >> vin;
@ -708,19 +708,19 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
if(mn.IsEnabled()) if(mn.IsEnabled())
{ {
if(fDebug) LogPrintf("dseg - Sending masternode entry - %s \n", mn.addr.ToString().c_str()); if(fDebug) LogPrintf("dseg - Sending Masternode entry - %s \n", mn.addr.ToString().c_str());
if(vin == CTxIn()){ if(vin == CTxIn()){
pfrom->PushMessage("dsee", mn.vin, mn.addr, mn.sig, mn.sigTime, mn.pubkey, mn.pubkey2, count, i, mn.lastTimeSeen, mn.protocolVersion); pfrom->PushMessage("dsee", mn.vin, mn.addr, mn.sig, mn.sigTime, mn.pubkey, mn.pubkey2, count, i, mn.lastTimeSeen, mn.protocolVersion);
} else if (vin == mn.vin) { } else if (vin == mn.vin) {
pfrom->PushMessage("dsee", mn.vin, mn.addr, mn.sig, mn.sigTime, mn.pubkey, mn.pubkey2, count, i, mn.lastTimeSeen, mn.protocolVersion); pfrom->PushMessage("dsee", mn.vin, mn.addr, mn.sig, mn.sigTime, mn.pubkey, mn.pubkey2, count, i, mn.lastTimeSeen, mn.protocolVersion);
LogPrintf("dseg - Sent 1 masternode entries to %s\n", pfrom->addr.ToString().c_str()); LogPrintf("dseg - Sent 1 Masternode entries to %s\n", pfrom->addr.ToString().c_str());
return; return;
} }
i++; i++;
} }
} }
LogPrintf("dseg - Sent %d masternode entries to %s\n", i, pfrom->addr.ToString().c_str()); LogPrintf("dseg - Sent %d Masternode entries to %s\n", i, pfrom->addr.ToString().c_str());
} }
} }
@ -729,10 +729,10 @@ std::string CMasternodeMan::ToString()
{ {
std::ostringstream info; std::ostringstream info;
info << "masternodes: " << (int)vMasternodes.size() << info << "Masternodes: " << (int)vMasternodes.size() <<
", peers who asked us for masternode list: " << (int)mAskedUsForMasternodeList.size() << ", peers who asked us for Masternode list: " << (int)mAskedUsForMasternodeList.size() <<
", peers we asked for masternode list: " << (int)mWeAskedForMasternodeList.size() << ", peers we asked for Masternode list: " << (int)mWeAskedForMasternodeList.size() <<
", entries in masternode list we asked for: " << (int)mWeAskedForMasternodeListEntry.size(); ", entries in Masternode list we asked for: " << (int)mWeAskedForMasternodeListEntry.size();
return info.str(); return info.str();
} }

View File

@ -26,7 +26,8 @@ class CMasternodeMan;
extern CMasternodeMan mnodeman; extern CMasternodeMan mnodeman;
void DumpMasternodes(); void DumpMasternodes();
/** Access to the MN database (masternodes.dat) */ /** Access to the MN database (masternodes.dat)
*/
class CMasternodeDB class CMasternodeDB
{ {
private: private:
@ -45,11 +46,11 @@ private:
// map to hold all MNs // map to hold all MNs
std::vector<CMasternode> vMasternodes; std::vector<CMasternode> vMasternodes;
// who's asked for the masternode list and the last time // who's asked for the Masternode list and the last time
std::map<CNetAddr, int64_t> mAskedUsForMasternodeList; std::map<CNetAddr, int64_t> mAskedUsForMasternodeList;
// who we asked for the masternode list and the last time // who we asked for the Masternode list and the last time
std::map<CNetAddr, int64_t> mWeAskedForMasternodeList; std::map<CNetAddr, int64_t> mWeAskedForMasternodeList;
// which masternodes we've asked for // which Masternodes we've asked for
std::map<COutPoint, int64_t> mWeAskedForMasternodeListEntry; std::map<COutPoint, int64_t> mWeAskedForMasternodeListEntry;
public: public:
@ -73,17 +74,16 @@ public:
CMasternodeMan(); CMasternodeMan();
CMasternodeMan(CMasternodeMan& other); CMasternodeMan(CMasternodeMan& other);
// Add an entry /// Add an entry
bool Add(CMasternode &mn); bool Add(CMasternode &mn);
// Check all masternodes /// Check all Masternodes
void Check(); void Check();
// Check all masternodes and remove inactive /// Check all Masternodes and remove inactive
void CheckAndRemove(); void CheckAndRemove();
// Clear masternode vector /// Clear Masternode vector
void Clear(); void Clear();
int CountEnabled(); int CountEnabled();
@ -92,16 +92,16 @@ public:
void DsegUpdate(CNode* pnode); void DsegUpdate(CNode* pnode);
// Find an entry /// Find an entry
CMasternode* Find(const CTxIn& vin); CMasternode* Find(const CTxIn& vin);
//Find an entry thta do not match every entry provided vector /// Find an entry thta do not match every entry provided vector
CMasternode* FindOldestNotInVec(const std::vector<CTxIn> &vVins); CMasternode* FindOldestNotInVec(const std::vector<CTxIn> &vVins);
// Find a random entry /// Find a random entry
CMasternode* FindRandom(); CMasternode* FindRandom();
// Get the current winner for this block /// Get the current winner for this block
CMasternode* GetCurrentMasterNode(int mod=1, int64_t nBlockHeight=0, int minProtocol=0); CMasternode* GetCurrentMasterNode(int mod=1, int64_t nBlockHeight=0, int minProtocol=0);
std::vector<CMasternode> GetFullMasternodeVector() { Check(); return vMasternodes; } std::vector<CMasternode> GetFullMasternodeVector() { Check(); return vMasternodes; }
@ -113,7 +113,7 @@ public:
void ProcessMasternodeConnections(); void ProcessMasternodeConnections();
// Return the number of (unique) masternodes /// Return the number of (unique) Masternodes
int size() { return vMasternodes.size(); } int size() { return vMasternodes.size(); }
std::string ToString(); std::string ToString();

View File

@ -326,12 +326,14 @@ inline int64_t GetPerformanceCounter()
return nCounter; return nCounter;
} }
/// returns the current time as UTC milliseconds
inline int64_t GetTimeMillis() inline int64_t GetTimeMillis()
{ {
return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
} }
/// returns the current time as UTC microseconds
inline int64_t GetTimeMicros() inline int64_t GetTimeMicros()
{ {
return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -