Merge branch 'v0.12.0.x' of https://github.com/dashpay/dash into v0.12.0.x

This commit is contained in:
Evan Duffield 2015-07-14 07:55:07 -07:00
commit d228b4bf47
15 changed files with 383 additions and 360 deletions

View File

@ -17,63 +17,64 @@ void CActiveMasternode::ManageStatus()
if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n"); if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n");
//need correct adjusted time to send ping //need correct blocks to send ping
bool fIsInitialDownload = IsInitialBlockDownload(); if(IsInitialBlockDownload()) {
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;
} }
if(status == MASTERNODE_INPUT_TOO_NEW || status == MASTERNODE_NOT_CAPABLE || status == MASTERNODE_SYNC_IN_PROCESS){ if(status == MASTERNODE_INITIAL || status == MASTERNODE_SYNC_IN_PROCESS) {
status = MASTERNODE_NOT_PROCESSED; CMasternode *pmn;
pmn = mnodeman.Find(pubKeyMasternode);
if(pmn != NULL) {
pmn->Check();
if(pmn->IsEnabled()) EnableHotColdMasterNode(pmn->vin, pmn->addr);
}
} }
if(status == MASTERNODE_NOT_PROCESSED) { if(status != MASTERNODE_STARTED) {
// Set defaults
status = MASTERNODE_NOT_CAPABLE;
notCapableReason = "";
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; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
return; return;
} }
} else { } else {
service = CService(strMasterNodeAddr); service = CService(strMasterNodeAddr);
} }
LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString().c_str()); LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString());
if(Params().NetworkID() == CBaseChainParams::MAIN) { if(Params().NetworkID() == CBaseChainParams::MAIN) {
if(service.GetPort() != 9999) { if(service.GetPort() != 9999) {
notCapableReason = "Invalid port: " + boost::lexical_cast<string>(service.GetPort()) + " - only 9999 is supported on mainnet."; notCapableReason = "Invalid port: " + boost::lexical_cast<string>(service.GetPort()) + " - only 9999 is supported on mainnet.";
status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
return; return;
} }
} else if(service.GetPort() == 9999) { } else if(service.GetPort() == 9999) {
notCapableReason = "Invalid port: " + boost::lexical_cast<string>(service.GetPort()) + " - 9999 is only supported on mainnet."; notCapableReason = "Invalid port: " + boost::lexical_cast<string>(service.GetPort()) + " - 9999 is only supported on mainnet.";
status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
return; return;
} }
if(!ConnectNode((CAddress)service, service.ToString().c_str())){ if(!ConnectNode((CAddress)service, service.ToString().c_str())){
notCapableReason = "Could not connect to " + service.ToString(); notCapableReason = "Could not connect to " + service.ToString();
status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
return; return;
} }
if(pwalletMain->IsLocked()){ if(pwalletMain->IsLocked()){
notCapableReason = "Wallet is locked."; notCapableReason = "Wallet is locked.";
status = MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason);
LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason.c_str());
return; return;
} }
// Set defaults
status = MASTERNODE_NOT_CAPABLE;
notCapableReason = "Unknown. Check debug.log for more information.";
// Choose coins to use // Choose coins to use
CPubKey pubKeyCollateralAddress; CPubKey pubKeyCollateralAddress;
@ -84,16 +85,11 @@ void CActiveMasternode::ManageStatus()
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
notCapableReason = "Input must have least " + boost::lexical_cast<string>(MASTERNODE_MIN_CONFIRMATIONS) + notCapableReason = "Input must have least " + boost::lexical_cast<string>(MASTERNODE_MIN_CONFIRMATIONS) +
" confirmations - " + boost::lexical_cast<string>(GetInputAge(vin)) + " confirmations"; " confirmations - " + boost::lexical_cast<string>(GetInputAge(vin)) + " confirmations";
LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason.c_str()); LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason);
status = MASTERNODE_INPUT_TOO_NEW; status = MASTERNODE_INPUT_TOO_NEW;
return; return;
} }
LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n");
status = MASTERNODE_IS_CAPABLE;
notCapableReason = "";
pwalletMain->LockCoin(vin.prevout); pwalletMain->LockCoin(vin.prevout);
// send to all nodes // send to all nodes
@ -102,31 +98,48 @@ void CActiveMasternode::ManageStatus()
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode))
{ {
LogPrintf("Register::ManageStatus() - Error upon calling SetKey: %s\n", errorMessage.c_str()); notCapableReason = "Error upon calling SetKey: " + errorMessage;
LogPrintf("Register::ManageStatus() - %s\n", notCapableReason);
return; return;
} }
if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage)) { if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage)) {
LogPrintf("CActiveMasternode::ManageStatus() - Error on Register: %s\n", errorMessage.c_str()); notCapableReason = "Error on Register: " + errorMessage;
LogPrintf("Register::ManageStatus() - %s\n", notCapableReason);
return;
} }
LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n");
status = MASTERNODE_STARTED;
return; return;
} else { } else {
notCapableReason = "Could not find suitable coins!"; notCapableReason = "Could not find suitable coins!";
LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason.c_str()); LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason);
return;
} }
} }
//send to all peers //send to all peers
if(!Mnping(errorMessage)) { if(!SendMasternodePing(errorMessage)) {
LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s\n", errorMessage.c_str()); LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s\n", errorMessage);
} }
} }
bool CActiveMasternode::Mnping(std::string& errorMessage) { std::string CActiveMasternode::GetStatus() {
if(status != MASTERNODE_IS_CAPABLE && status != MASTERNODE_REMOTELY_ENABLED) { switch (status) {
case MASTERNODE_INITIAL: return "node just started, not yet activated";
case MASTERNODE_SYNC_IN_PROCESS: return "sync in process. Must wait until client is synced to start";
case MASTERNODE_INPUT_TOO_NEW: return "masternode input must have at least 15 confirmations";
case MASTERNODE_NOT_CAPABLE: return "not capable masternode: " + notCapableReason;
case MASTERNODE_STARTED: return "masternode successfully started";
default: return "unknown";
}
}
bool CActiveMasternode::SendMasternodePing(std::string& errorMessage) {
if(status != MASTERNODE_STARTED) {
errorMessage = "Masternode is not in a running status"; errorMessage = "Masternode is not in a running status";
LogPrintf("CActiveMasternode::Mnping() - Error: %s\n", errorMessage.c_str());
return false; return false;
} }
@ -135,43 +148,42 @@ bool CActiveMasternode::Mnping(std::string& errorMessage) {
if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode))
{ {
LogPrintf("CActiveMasternode::Mnping() - Error upon calling SetKey: %s\n", errorMessage.c_str()); errorMessage = strprintf("Error upon calling SetKey: %s\n", errorMessage);
return false; return false;
} }
return Mnping(vin, service, keyMasternode, pubKeyMasternode, errorMessage); LogPrintf("CActiveMasternode::SendMasternodePing() - Relay Masternode Ping vin = %s\n", vin.ToString());
}
bool CActiveMasternode::Mnping(CTxIn vin, CService service, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage) {
//send to all peers
LogPrintf("CActiveMasternode::Mnping() - RelayMasternodeEntryPing vin = %s\n", vin.ToString().c_str());
CMasternodePing mnp(vin); CMasternodePing mnp(vin);
if(!mnp.Sign(keyMasternode, pubKeyMasternode)) if(!mnp.Sign(keyMasternode, pubKeyMasternode))
{ {
errorMessage = "Couldn't sign Masternode Ping";
return false; return false;
} }
// Update Last Seen timestamp in Masternode list // Update lastPing for our masternode in Masternode list
CMasternode* pmn = mnodeman.Find(vin); CMasternode* pmn = mnodeman.Find(vin);
if(pmn != NULL) if(pmn != NULL)
{ {
pmn->UpdateLastSeen(); if(pmn->IsPingedWithin(MASTERNODE_PING_SECONDS, mnp.sigTime)){
errorMessage = "Too early to send Masternode Ping";
return false;
}
pmn->lastPing = mnp;
mapSeenMasternodePing[mnp.GetHash()] = mnp;
mnp.Relay();
return true;
} }
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(); errorMessage = "Darksend Masternode List doesn't include our Masternode, shutting down Masternode pinging service! " + vin.ToString();
LogPrintf("CActiveMasternode::Mnping() - Error: %s\n", retErrorMessage.c_str());
status = MASTERNODE_NOT_CAPABLE; status = MASTERNODE_NOT_CAPABLE;
notCapableReason = retErrorMessage; notCapableReason = errorMessage;
return false; return false;
} }
mapSeenMasternodePing[mnp.GetHash()] = mnp;
mnp.Relay();
return true;
} }
bool CActiveMasternode::Register(std::string strService, std::string strKeyMasternode, std::string txHash, std::string strOutputIndex, std::string& errorMessage) { bool CActiveMasternode::Register(std::string strService, std::string strKeyMasternode, std::string txHash, std::string strOutputIndex, std::string& errorMessage) {
@ -183,13 +195,13 @@ bool CActiveMasternode::Register(std::string strService, std::string strKeyMaste
if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) if(!darkSendSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode))
{ {
LogPrintf("CActiveMasternode::Register() - Error upon calling SetKey: %s\n", errorMessage.c_str()); LogPrintf("CActiveMasternode::Register() - Error upon calling SetKey: %s\n", errorMessage);
return false; return false;
} }
if(!GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress, txHash, strOutputIndex)) { if(!GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress, txHash, strOutputIndex)) {
errorMessage = "could not allocate vin"; errorMessage = "could not allocate vin";
LogPrintf("CActiveMasternode::Register() - Error: %s\n", errorMessage.c_str()); LogPrintf("CActiveMasternode::Register() - Error: %s\n", errorMessage);
return false; return false;
} }
@ -197,32 +209,35 @@ bool CActiveMasternode::Register(std::string strService, std::string strKeyMaste
} }
bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage) { bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string &retErrorMessage) {
CMasternodeBroadcast mnb;
CMasternodePing mnp(vin);
if(!mnp.Sign(keyMasternode, pubKeyMasternode)){
LogPrintf("CActiveMasternode::Register() - Failed to sign ping, vin: %s\n", vin.ToString());
return false;
}
mapSeenMasternodePing[mnp.GetHash()] = mnp;
LogPrintf("CActiveMasternode::Register() - Adding to Masternode list service: %s - vin: %s\n", service.ToString(), vin.ToString());
mnb = CMasternodeBroadcast(service, vin, pubKeyCollateralAddress, pubKeyMasternode, PROTOCOL_VERSION);
mnb.lastPing = mnp;
if(!mnb.Sign(keyCollateralAddress)){
LogPrintf("CActiveMasternode::Register() - Failed to sign broadcast, vin: %s\n", vin.ToString());
return false;
}
mapSeenMasternodeBroadcast[mnb.GetHash()] = mnb;
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());
CMasternodeBroadcast mnb(service, vin, pubKeyCollateralAddress, pubKeyMasternode, PROTOCOL_VERSION);
if(!mnb.Sign(keyCollateralAddress)){
//send to all peers
LogPrintf("CActiveMasternode::Register() - Failed to sign %s\n", vin.ToString().c_str());
return false;
}
CMasternode mn(mnb); CMasternode mn(mnb);
mn.UpdateLastSeen();
mnodeman.Add(mn); mnodeman.Add(mn);
} else {
pmn->UpdateFromNewBroadcast(mnb);
} }
if(pmn == NULL) pmn = mnodeman.Find(vin);
if(pmn != NULL)
{
CMasternodeBroadcast mnb(*pmn);
mapSeenMasternodeBroadcast[mnb.GetHash()] = mnb; //send to all peers
//send to all peers LogPrintf("CActiveMasternode::Register() - RelayElectionEntry vin = %s\n", vin.ToString());
LogPrintf("CActiveMasternode::Register() - RelayElectionEntry vin = %s\n", vin.ToString().c_str()); mnb.Relay();
mnb.Relay(false);
}
return true; return true;
} }
@ -232,8 +247,6 @@ bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secr
} }
bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex) { bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex) {
CScript pubScript;
// Find possible candidates // Find possible candidates
vector<COutput> possibleCoins = SelectCoinsMasternode(); vector<COutput> possibleCoins = SelectCoinsMasternode();
COutput *selectedOutput; COutput *selectedOutput;
@ -340,7 +353,7 @@ bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& newVin, CService& newServ
{ {
if(!fMasterNode) return false; if(!fMasterNode) return false;
status = MASTERNODE_REMOTELY_ENABLED; status = MASTERNODE_STARTED;
//The values below are needed for signing mnping messages going forward //The values below are needed for signing mnping messages going forward
this->vin = newVin; this->vin = newVin;

View File

@ -16,6 +16,20 @@
// Responsible for activating the Masternode and pinging the network // Responsible for activating the Masternode and pinging the network
class CActiveMasternode class CActiveMasternode
{ {
private:
// critical section to protect the inner data structures
mutable CCriticalSection cs;
/// Ping Masternode
bool SendMasternodePing(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
bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex);
bool GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey);
public: public:
// Initialized by init.cpp // Initialized by init.cpp
// Keys for the main Masternode // Keys for the main Masternode
@ -30,29 +44,21 @@ public:
CActiveMasternode() CActiveMasternode()
{ {
status = MASTERNODE_NOT_PROCESSED; status = MASTERNODE_INITIAL;
} }
/// Manage status of main Masternode /// Manage status of main Masternode
void ManageStatus(); void ManageStatus();
std::string GetStatus();
/// Ping for main Masternode
bool Mnping(std::string& errorMessage);
/// Ping for any Masternode
bool Mnping(CTxIn vin, CService service, CKey key, CPubKey pubKey, std::string &retErrorMessage);
/// Register remote Masternode /// Register remote Masternode
bool Register(std::string strService, std::string strKey, std::string txHash, std::string strOutputIndex, std::string& errorMessage); 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);
vector<COutput> SelectCoinsMasternode(); vector<COutput> SelectCoinsMasternode();
bool GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey);
/// Enable hot wallet mode (run a Masternode with no funds) /// Enable cold wallet mode (run a Masternode with no funds)
bool EnableHotColdMasterNode(CTxIn& vin, CService& addr); bool EnableHotColdMasterNode(CTxIn& vin, CService& addr);
}; };

View File

@ -22,8 +22,6 @@
using namespace std; using namespace std;
using namespace boost; using namespace boost;
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
@ -2335,27 +2333,6 @@ void ThreadCheckDarkSendPool()
MilliSleep(1000); MilliSleep(1000);
//LogPrintf("ThreadCheckDarkSendPool::check timeout\n"); //LogPrintf("ThreadCheckDarkSendPool::check timeout\n");
darkSendPool.CheckTimeout();
darkSendPool.CheckForCompleteQueue();
if(c % 60 == 0)
{
LOCK(cs_main);
/*
cs_main is required for doing CMasternode.Check because something
is modifying the coins view without a mempool lock. It causes
segfaults from this code without the cs_main lock.
*/
mnodeman.CheckAndRemove();
mnodeman.ProcessMasternodeConnections();
masternodePayments.CleanPaymentList();
CleanTransactionLocksList();
}
if(c % MASTERNODE_PING_SECONDS == 0) activeMasternode.ManageStatus();
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 && RequestedMasternodeAssets <= 5){ if(c % 5 == 0 && RequestedMasternodeAssets <= 5){
bool fIsInitialDownload = IsInitialBlockDownload(); bool fIsInitialDownload = IsInitialBlockDownload();
@ -2403,8 +2380,10 @@ void ThreadCheckDarkSendPool()
} }
} }
} }
} else if(c % 60 == 0 && RequestedMasternodeAssets == 3){ } else if((c % 60 == 0 && RequestedMasternodeAssets >= 5 && RequestedMasternodeAssets < MASTERNODE_LIST_SYNCED) || //done syncing
RequestedMasternodeAssets = MASTERNODE_LIST_SYNCED; //done syncing (c % (5 * 60) == 0 && RequestedMasternodeAssets < 5)) { //couldn't find 5 peers in 5 minutes
RequestedMasternodeAssets = MASTERNODE_LIST_SYNCED;
c = 1; // reset counter
} }
if(c % 60 == 0){ if(c % 60 == 0){
@ -2417,8 +2396,37 @@ void ThreadCheckDarkSendPool()
} }
} }
if(darkSendPool.GetState() == POOL_STATUS_IDLE && c % 6 == 0){ if(RequestedMasternodeAssets == MASTERNODE_LIST_SYNCED) {
darkSendPool.DoAutomaticDenominating(); if(c % MASTERNODE_PING_SECONDS == 1) activeMasternode.ManageStatus(); // activate right after sync
if(c % 60 == 0)
{
LOCK(cs_main);
/*
cs_main is required for doing CMasternode.Check because something
is modifying the coins view without a mempool lock. It causes
segfaults from this code without the cs_main lock.
*/
mnodeman.CheckAndRemove();
mnodeman.ProcessMasternodeConnections();
masternodePayments.CleanPaymentList();
CleanTransactionLocksList();
}
if(c % 60 == 0){
//if we've used 1/5 of the Masternode list, then clear the list.
if((int)vecMasternodesUsed.size() > (int)mnodeman.size() / 5)
vecMasternodesUsed.clear();
}
if(c % MASTERNODES_DUMP_SECONDS == 0) DumpMasternodes();
darkSendPool.CheckTimeout();
darkSendPool.CheckForCompleteQueue();
if(darkSendPool.GetState() == POOL_STATUS_IDLE && c % 6 == 0){
darkSendPool.DoAutomaticDenominating();
}
} }
} }
} }

View File

@ -267,6 +267,9 @@ public:
*/ */
class CDarksendPool class CDarksendPool
{ {
private:
mutable CCriticalSection cs_darksend;
public: public:
enum messages { enum messages {
ERR_ALREADY_HAVE, ERR_ALREADY_HAVE,

View File

@ -1490,7 +1490,6 @@ bool AppInit2(boost::thread_group& threadGroup)
return InitError(_("You must specify a masternodeprivkey in the configuration. Please see documentation for help.")); return InitError(_("You must specify a masternodeprivkey in the configuration. Please see documentation for help."));
} }
if(Params().NetworkID() != CBaseChainParams::REGTEST) activeMasternode.ManageStatus();
} }
if(GetBoolArg("-mnconflock", true)) { if(GetBoolArg("-mnconflock", true)) {

View File

@ -27,7 +27,7 @@ class CConsensusVote;
class CTransaction; class CTransaction;
class CTransactionLock; class CTransactionLock;
static const int MIN_INSTANTX_PROTO_VERSION = 70089; static const int MIN_INSTANTX_PROTO_VERSION = 70090;
extern map<uint256, CTransaction> mapTxLockReq; extern map<uint256, CTransaction> mapTxLockReq;
extern map<uint256, CTransaction> mapTxLockReqRejected; extern map<uint256, CTransaction> mapTxLockReqRejected;

View File

@ -4180,11 +4180,9 @@ void static ProcessGetData(CNode* pfrom)
if (!pushed && inv.type == MSG_MASTERNODE_ANNOUNCE) { if (!pushed && inv.type == MSG_MASTERNODE_ANNOUNCE) {
if(mapSeenMasternodeBroadcast.count(inv.hash)){ if(mapSeenMasternodeBroadcast.count(inv.hash)){
bool fRequested = false; // Requested full masternode list
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000); ss.reserve(1000);
ss << mapSeenMasternodeBroadcast[inv.hash]; ss << mapSeenMasternodeBroadcast[inv.hash];
ss << fRequested;
pfrom->PushMessage("mnb", ss); pfrom->PushMessage("mnb", ss);
pushed = true; pushed = true;
} }
@ -4192,11 +4190,9 @@ void static ProcessGetData(CNode* pfrom)
if (!pushed && inv.type == MSG_MASTERNODE_PING) { if (!pushed && inv.type == MSG_MASTERNODE_PING) {
if(mapSeenMasternodePing.count(inv.hash)){ if(mapSeenMasternodePing.count(inv.hash)){
bool fRequested = false; // Requested full masternode list
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000); ss.reserve(1000);
ss << mapSeenMasternodePing[inv.hash]; ss << mapSeenMasternodePing[inv.hash];
ss << fRequested;
pfrom->PushMessage("mnp", ss); pfrom->PushMessage("mnp", ss);
pushed = true; pushed = true;
} }

View File

@ -40,8 +40,8 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s
CTransaction txCollateral; CTransaction txCollateral;
uint256 nBlockHash; uint256 nBlockHash;
if(!GetTransaction(nTxCollateralHash, txCollateral, nBlockHash, true)){ if(!GetTransaction(nTxCollateralHash, txCollateral, nBlockHash, true)){
strError = "Can't find collateral tx %s\n", txCollateral.ToString().c_str(); strError = strprintf("Can't find collateral tx %s", txCollateral.ToString());
LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - Can't find collateral tx %s\n", txCollateral.ToString().c_str()); LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - %s\n", strError);
return false; return false;
} }
@ -54,16 +54,16 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s
bool foundOpReturn = false; bool foundOpReturn = false;
BOOST_FOREACH(const CTxOut o, txCollateral.vout){ BOOST_FOREACH(const CTxOut o, txCollateral.vout){
if(!o.scriptPubKey.IsNormalPaymentScript() && !o.scriptPubKey.IsUnspendable()){ if(!o.scriptPubKey.IsNormalPaymentScript() && !o.scriptPubKey.IsUnspendable()){
strError = "Invalid Script"; strError = strprintf("Invalid Script %s", txCollateral.ToString());
LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - Invalid Script %s\n", txCollateral.ToString()); LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - %s\n", strError);
return false; return false;
} }
if(o.scriptPubKey == findScript && o.nValue >= BUDGET_FEE_TX) foundOpReturn = true; if(o.scriptPubKey == findScript && o.nValue >= BUDGET_FEE_TX) foundOpReturn = true;
} }
if(!foundOpReturn){ if(!foundOpReturn){
strError = "Couldn't find opReturn"; strError = strprintf("Couldn't find opReturn %s", txCollateral.ToString());
LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - Couldn't find opReturn %s\n", txCollateral.ToString()); LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - %s\n", strError);
return false; return false;
} }
@ -79,8 +79,8 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, s
} }
if(conf < BUDGET_FEE_CONFIRMATIONS){ if(conf < BUDGET_FEE_CONFIRMATIONS){
strError = "Collateral requires at least 6 confirmations - " + boost::lexical_cast<std::string>(conf) + " confirmations "; strError = strprintf("Collateral requires at least %d confirmations - %d confirmations", BUDGET_FEE_CONFIRMATIONS, conf);
LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - Collateral requires at least 6 confirmations - %s - %d confirmations\n", txCollateral.GetHash().ToString(), conf); LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - %s - %d confirmations\n", strError, conf);
return false; return false;
} }

View File

@ -73,8 +73,7 @@ CMasternode::CMasternode()
sig = std::vector<unsigned char>(); sig = std::vector<unsigned char>();
activeState = MASTERNODE_ENABLED; activeState = MASTERNODE_ENABLED;
sigTime = GetAdjustedTime(); sigTime = GetAdjustedTime();
lastMnping = 0; lastPing = CMasternodePing();
lastTimeSeen = 0;
cacheInputAge = 0; cacheInputAge = 0;
cacheInputAgeBlock = 0; cacheInputAgeBlock = 0;
unitTest = false; unitTest = false;
@ -96,8 +95,7 @@ CMasternode::CMasternode(const CMasternode& other)
sig = other.sig; sig = other.sig;
activeState = other.activeState; activeState = other.activeState;
sigTime = other.sigTime; sigTime = other.sigTime;
lastMnping = other.lastMnping; lastPing = other.lastPing;
lastTimeSeen = other.lastTimeSeen;
cacheInputAge = other.cacheInputAge; cacheInputAge = other.cacheInputAge;
cacheInputAgeBlock = other.cacheInputAgeBlock; cacheInputAgeBlock = other.cacheInputAgeBlock;
unitTest = other.unitTest; unitTest = other.unitTest;
@ -109,29 +107,6 @@ CMasternode::CMasternode(const CMasternode& other)
nVotedTimes = other.nVotedTimes; nVotedTimes = other.nVotedTimes;
} }
CMasternode::CMasternode(CService newAddr, CTxIn newVin, CPubKey newPubkey, std::vector<unsigned char> newSig, int64_t newSigTime, CPubKey newPubkey2, int protocolVersionIn)
{
LOCK(cs);
vin = newVin;
addr = newAddr;
pubkey = newPubkey;
pubkey2 = newPubkey2;
sig = newSig;
activeState = MASTERNODE_ENABLED;
sigTime = newSigTime;
lastMnping = 0;
lastTimeSeen = 0;
cacheInputAge = 0;
cacheInputAgeBlock = 0;
unitTest = false;
allowFreeTx = true;
protocolVersion = protocolVersionIn;
nLastDsq = 0;
nScanningErrorCount = 0;
nLastScanningErrorBlockHeight = 0;
nVotedTimes = 0;
}
CMasternode::CMasternode(const CMasternodeBroadcast& mnb) CMasternode::CMasternode(const CMasternodeBroadcast& mnb)
{ {
LOCK(cs); LOCK(cs);
@ -142,8 +117,7 @@ CMasternode::CMasternode(const CMasternodeBroadcast& mnb)
sig = mnb.sig; sig = mnb.sig;
activeState = MASTERNODE_ENABLED; activeState = MASTERNODE_ENABLED;
sigTime = mnb.sigTime; sigTime = mnb.sigTime;
lastMnping = 0; lastPing = mnb.lastPing;
lastTimeSeen = 0;
cacheInputAge = 0; cacheInputAge = 0;
cacheInputAgeBlock = 0; cacheInputAgeBlock = 0;
unitTest = false; unitTest = false;
@ -165,6 +139,11 @@ void CMasternode::UpdateFromNewBroadcast(CMasternodeBroadcast& mnb)
sig = mnb.sig; sig = mnb.sig;
protocolVersion = mnb.protocolVersion; protocolVersion = mnb.protocolVersion;
addr = mnb.addr; addr = mnb.addr;
int nDoS = 0;
if(mnb.lastPing == CMasternodePing() || (mnb.lastPing != CMasternodePing() && mnb.lastPing.CheckAndUpdate(nDoS))) {
lastPing = mnb.lastPing;
mapSeenMasternodePing[lastPing.GetHash()] = lastPing;
}
} }
// //
@ -201,12 +180,12 @@ void CMasternode::Check()
if(activeState == MASTERNODE_VIN_SPENT) return; if(activeState == MASTERNODE_VIN_SPENT) return;
if(!UpdatedWithin(MASTERNODE_REMOVAL_SECONDS)){ if(!IsPingedWithin(MASTERNODE_REMOVAL_SECONDS)){
activeState = MASTERNODE_REMOVE; activeState = MASTERNODE_REMOVE;
return; return;
} }
if(!UpdatedWithin(MASTERNODE_EXPIRATION_SECONDS)){ if(!IsPingedWithin(MASTERNODE_EXPIRATION_SECONDS)){
activeState = MASTERNODE_EXPIRED; activeState = MASTERNODE_EXPIRED;
return; return;
} }
@ -260,8 +239,7 @@ CMasternodeBroadcast::CMasternodeBroadcast()
sig = std::vector<unsigned char>(); sig = std::vector<unsigned char>();
activeState = MASTERNODE_ENABLED; activeState = MASTERNODE_ENABLED;
sigTime = GetAdjustedTime(); sigTime = GetAdjustedTime();
lastMnping = 0; lastPing = CMasternodePing();
lastTimeSeen = 0;
cacheInputAge = 0; cacheInputAge = 0;
cacheInputAgeBlock = 0; cacheInputAgeBlock = 0;
unitTest = false; unitTest = false;
@ -280,8 +258,7 @@ CMasternodeBroadcast::CMasternodeBroadcast(CService newAddr, CTxIn newVin, CPubK
sig = std::vector<unsigned char>(); sig = std::vector<unsigned char>();
activeState = MASTERNODE_ENABLED; activeState = MASTERNODE_ENABLED;
sigTime = GetAdjustedTime(); sigTime = GetAdjustedTime();
lastMnping = 0; lastPing = CMasternodePing();
lastTimeSeen = 0;
cacheInputAge = 0; cacheInputAge = 0;
cacheInputAgeBlock = 0; cacheInputAgeBlock = 0;
unitTest = false; unitTest = false;
@ -292,32 +269,32 @@ CMasternodeBroadcast::CMasternodeBroadcast(CService newAddr, CTxIn newVin, CPubK
nLastScanningErrorBlockHeight = 0; nLastScanningErrorBlockHeight = 0;
} }
CMasternodeBroadcast::CMasternodeBroadcast(const CMasternode& other) CMasternodeBroadcast::CMasternodeBroadcast(const CMasternode& mn)
{ {
vin = other.vin; vin = mn.vin;
addr = other.addr; addr = mn.addr;
pubkey = other.pubkey; pubkey = mn.pubkey;
pubkey2 = other.pubkey2; pubkey2 = mn.pubkey2;
sig = other.sig; sig = mn.sig;
activeState = other.activeState; activeState = mn.activeState;
sigTime = other.sigTime; sigTime = mn.sigTime;
lastMnping = other.lastMnping; lastPing = mn.lastPing;
lastTimeSeen = other.lastTimeSeen; cacheInputAge = mn.cacheInputAge;
cacheInputAge = other.cacheInputAge; cacheInputAgeBlock = mn.cacheInputAgeBlock;
cacheInputAgeBlock = other.cacheInputAgeBlock; unitTest = mn.unitTest;
unitTest = other.unitTest; allowFreeTx = mn.allowFreeTx;
allowFreeTx = other.allowFreeTx; protocolVersion = mn.protocolVersion;
protocolVersion = other.protocolVersion; nLastDsq = mn.nLastDsq;
nLastDsq = other.nLastDsq; nScanningErrorCount = mn.nScanningErrorCount;
nScanningErrorCount = other.nScanningErrorCount; nLastScanningErrorBlockHeight = mn.nLastScanningErrorBlockHeight;
nLastScanningErrorBlockHeight = other.nLastScanningErrorBlockHeight;
} }
bool CMasternodeBroadcast::CheckAndUpdate(int& nDos, bool fRequested) bool CMasternodeBroadcast::CheckAndUpdate(int& nDos)
{ {
// make sure signature isn't in the future (past is OK) // make sure signature isn't in the future (past is OK)
if (sigTime > GetAdjustedTime() + 60 * 60) { if (sigTime > GetAdjustedTime() + 60 * 60) {
LogPrintf("mnb - Signature rejected, too far into the future %s\n", vin.ToString().c_str()); LogPrintf("mnb - Signature rejected, too far into the future %s\n", vin.ToString());
nDos = 1;
return false; return false;
} }
@ -367,35 +344,39 @@ bool CMasternodeBroadcast::CheckAndUpdate(int& nDos, bool fRequested)
//search existing Masternode list, this is where we update existing Masternodes with new mnb broadcasts //search existing Masternode list, this is where we update existing Masternodes with new mnb broadcasts
CMasternode* pmn = mnodeman.Find(vin); CMasternode* pmn = mnodeman.Find(vin);
// if we are masternode but with undefined vin and this mnb is ours (matches our Masternode privkey) then just skip this part // no such masternode or it's not enabled already, nothing to update
if(pmn != NULL && !(fMasterNode && activeMasternode.vin == CTxIn() && pubkey2 == activeMasternode.pubKeyMasternode)) if(pmn == NULL || (pmn != NULL && !pmn->IsEnabled())) return true;
{
// if Requested, we don't want to update this info
if(fRequested) { Relay(false); return true;}
// mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below, // mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below,
// after that they just need to match // after that they just need to match
if(pmn->pubkey == pubkey && !pmn->UpdatedWithin(MASTERNODE_MIN_MNB_SECONDS)){ if(pmn->pubkey == pubkey && !pmn->IsBroadcastedWithin(MASTERNODE_MIN_MNB_SECONDS)) {
pmn->UpdateLastSeen(); //take the newest entry
LogPrintf("mnb - Got updated entry for %s\n", addr.ToString().c_str());
if(pmn->sigTime < sigTime){ //take the newest entry pmn->UpdateFromNewBroadcast((*this));
LogPrintf("mnb - Got updated entry for %s\n", addr.ToString().c_str()); pmn->Check();
if(pmn->IsEnabled()) Relay();
pmn->UpdateFromNewBroadcast((*this));
pmn->Check();
if(pmn->IsEnabled()) {
Relay(fRequested);
}
}
}
} }
return true; return true;
} }
bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS, bool fRequested) bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS)
{ {
// we are a masternode with the same vin (i.e. already activated) and this mnb is ours (matches our Masternode privkey)
// so nothing to do here for us
if(fMasterNode && vin.prevout == activeMasternode.vin.prevout && pubkey2 == activeMasternode.pubKeyMasternode)
return true;
// search existing Masternode list
CMasternode* pmn = mnodeman.Find(vin);
if(pmn != NULL) {
// nothing to do here if we already know about this masternode and it's enabled
if(pmn->IsEnabled()) return true;
// if it's not enabled, remove old MN first and continue
else mnodeman.Remove(pmn->vin);
}
CValidationState state; CValidationState state;
CMutableTransaction tx = CMutableTransaction(); CMutableTransaction tx = CMutableTransaction();
CTxOut vout = CTxOut(999.99*COIN, darkSendPool.collateralPubKey); CTxOut vout = CTxOut(999.99*COIN, darkSendPool.collateralPubKey);
@ -427,9 +408,8 @@ bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS, bool fRequested)
} }
} }
// add our Masternode LogPrintf("mnb - Got NEW Masternode entry %s %s\n", addr.ToString(), vin.ToString());
CMasternode mn((*this)); CMasternode mn(*this);
mn.UpdateLastSeen(lastTimeSeen);
mnodeman.Add(mn); mnodeman.Add(mn);
// if it matches our Masternode privkey, then we've been remotely activated // if it matches our Masternode privkey, then we've been remotely activated
@ -440,7 +420,7 @@ bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS, bool fRequested)
bool isLocal = addr.IsRFC1918() || addr.IsLocal(); bool isLocal = addr.IsRFC1918() || addr.IsLocal();
if(Params().NetworkID() == CBaseChainParams::REGTEST) isLocal = false; if(Params().NetworkID() == CBaseChainParams::REGTEST) isLocal = false;
if(!fRequested && !isLocal) Relay(fRequested); if(!isLocal) Relay();
return true; return true;
} else { } else {
@ -451,7 +431,7 @@ bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS, bool fRequested)
return false; return false;
} }
void CMasternodeBroadcast::Relay(bool fRequested) void CMasternodeBroadcast::Relay()
{ {
CInv inv(MSG_MASTERNODE_ANNOUNCE, GetHash()); CInv inv(MSG_MASTERNODE_ANNOUNCE, GetHash());
RelayInv(inv); RelayInv(inv);
@ -484,13 +464,17 @@ bool CMasternodeBroadcast::Sign(CKey& keyCollateralAddress)
CMasternodePing::CMasternodePing() CMasternodePing::CMasternodePing()
{ {
vin = CTxIn(); vin = CTxIn();
blockHash = chainActive[chainActive.Height() - 12]->GetBlockHash(); blockHash = uint256(0);
sigTime = 0;
vchSig = std::vector<unsigned char>();
} }
CMasternodePing::CMasternodePing(CTxIn& newVin) CMasternodePing::CMasternodePing(CTxIn& newVin)
{ {
vin = newVin; vin = newVin;
blockHash = chainActive[chainActive.Height() - 12]->GetBlockHash(); blockHash = chainActive[chainActive.Height() - 12]->GetBlockHash();
sigTime = GetAdjustedTime();
vchSig = std::vector<unsigned char>();
} }
@ -518,62 +502,70 @@ bool CMasternodePing::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
bool CMasternodePing::CheckAndUpdate(int& nDos) bool CMasternodePing::CheckAndUpdate(int& nDos)
{ {
if (sigTime > GetAdjustedTime() + 60 * 60) { if (sigTime > GetAdjustedTime() + 60 * 60) {
LogPrintf("mnping - Signature rejected, too far into the future %s\n", vin.ToString().c_str()); LogPrintf("CMasternodePing::CheckAndUpdate - Signature rejected, too far into the future %s\n", vin.ToString().c_str());
nDos = 1;
return false; return false;
} }
if (sigTime <= GetAdjustedTime() - 60 * 60) { if (sigTime <= GetAdjustedTime() - 60 * 60) {
LogPrintf("mnping - Signature rejected, too far into the past %s - %d %d \n", vin.ToString().c_str(), sigTime, GetAdjustedTime()); LogPrintf("CMasternodePing::CheckAndUpdate - Signature rejected, too far into the past %s - %d %d \n", vin.ToString().c_str(), sigTime, GetAdjustedTime());
nDos = 1;
return false; return false;
} }
// see if we have this Masternode // see if we have this Masternode
CMasternode* pmn = mnodeman.Find(vin); CMasternode* pmn = mnodeman.Find(vin);
if(pmn != NULL && pmn->protocolVersion >= nMasternodeMinProtocol) if(pmn != NULL && pmn->IsEnabled() && pmn->protocolVersion >= nMasternodeMinProtocol)
{ {
// LogPrintf("mnping - Found corresponding mn for vin: %s\n", vin.ToString().c_str()); // LogPrintf("mnping - Found corresponding mn for vin: %s\n", vin.ToString().c_str());
// take this only if it's newer and last ping was more then MASTERNODE_MIN_MNP_SECONDS ago // update only if there is no known ping for this masternode or
if(sigTime - pmn->lastMnping > MASTERNODE_MIN_MNP_SECONDS-60) // last ping was more then MASTERNODE_MIN_MNP_SECONDS-60 ago comparing to this one
if(!pmn->IsPingedWithin(MASTERNODE_MIN_MNP_SECONDS - 60, sigTime))
{ {
std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime); std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime);
std::string errorMessage = ""; std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)) if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage))
{ {
LogPrintf("mnping - Got bad Masternode address signature %s\n", vin.ToString()); LogPrintf("CMasternodePing::CheckAndUpdate - Got bad Masternode address signature %s\n", vin.ToString());
nDos = 33; nDos = 33;
return false; return false;
} }
pmn->lastMnping = sigTime;
BlockMap::iterator mi = mapBlockIndex.find(blockHash); BlockMap::iterator mi = mapBlockIndex.find(blockHash);
if (mi != mapBlockIndex.end() && (*mi).second) if (mi != mapBlockIndex.end() && (*mi).second)
{ {
if((*mi).second->nHeight < chainActive.Height() - 24) if((*mi).second->nHeight < chainActive.Height() - 24)
{ {
LogPrintf("mnping - Masternode %s block hash %s is too old\n", vin.ToString(), blockHash.ToString()); LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is too old\n", vin.ToString(), blockHash.ToString());
// Do nothing here (no Masternode update, no mnping relay) // Do nothing here (no Masternode update, no mnping relay)
// Let this node to be visible but fail to accept mnping // Let this node to be visible but fail to accept mnping
return false; return false;
} }
} else { } else {
if (fDebug) LogPrintf("mnping - Masternode %s block hash %s is unknown\n", vin.ToString(), blockHash.ToString()); if (fDebug) LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is unknown\n", vin.ToString(), blockHash.ToString());
// maybe we stuck so we shouldn't ban this node, just fail to accept it // maybe we stuck so we shouldn't ban this node, just fail to accept it
// TODO: or should we also request this block? // TODO: or should we also request this block?
return false; return false;
} }
pmn->UpdateLastSeen(); pmn->lastPing = *this;
pmn->Check(); pmn->Check();
if(!pmn->IsEnabled()) return false; if(!pmn->IsEnabled()) return false;
if(fDebug) LogPrintf("CMasternodePing::CheckAndUpdate - Masternode ping accepted, vin: %s\n", vin.ToString());
Relay(); Relay();
return true; return true;
} }
if(fDebug) LogPrintf("CMasternodePing::CheckAndUpdate - Masternode ping arrived too early, vin: %s\n", vin.ToString());
nDos = 1;
return false;
} }
if(fDebug) LogPrintf("CMasternodePing::CheckAndUpdate - Couldn't find compatible Masternode entry, vin: %s\n", vin.ToString());
return false; return false;
} }

View File

@ -13,15 +13,11 @@
#include "main.h" #include "main.h"
#include "timedata.h" #include "timedata.h"
#define MASTERNODE_NOT_PROCESSED 0 // initial state #define MASTERNODE_INITIAL 0 // initial state
#define MASTERNODE_IS_CAPABLE 1 #define MASTERNODE_SYNC_IN_PROCESS 1
#define MASTERNODE_NOT_CAPABLE 2 #define MASTERNODE_INPUT_TOO_NEW 2
#define MASTERNODE_STOPPED 3 #define MASTERNODE_NOT_CAPABLE 3
#define MASTERNODE_INPUT_TOO_NEW 4 #define MASTERNODE_STARTED 4
#define MASTERNODE_PORT_NOT_OPEN 6
#define MASTERNODE_PORT_OPEN 7
#define MASTERNODE_SYNC_IN_PROCESS 8
#define MASTERNODE_REMOTELY_ENABLED 9
#define MASTERNODE_MIN_CONFIRMATIONS 15 #define MASTERNODE_MIN_CONFIRMATIONS 15
#define MASTERNODE_MIN_MNP_SECONDS (30*60) #define MASTERNODE_MIN_MNP_SECONDS (30*60)
@ -39,6 +35,75 @@ extern map<int64_t, uint256> mapCacheBlockHashes;
bool GetBlockHash(uint256& hash, int nBlockHeight); bool GetBlockHash(uint256& hash, int nBlockHeight);
//
// The Masternode Ping Class : Contains a different serialize method for sending pings from masternodes throughout the network
//
class CMasternodePing
{
public:
CTxIn vin;
uint256 blockHash;
int64_t sigTime; //mnb message times
std::vector<unsigned char> vchSig;
//removed stop
CMasternodePing();
CMasternodePing(CTxIn& newVin);
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(vin);
READWRITE(blockHash);
READWRITE(sigTime);
READWRITE(vchSig);
}
bool CheckAndUpdate(int& nDos);
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
void Relay();
uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << vin;
ss << sigTime;
return ss.GetHash();
}
void swap(CMasternodePing& first, CMasternodePing& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// by swapping the members of two classes,
// the two classes are effectively swapped
swap(first.vin, second.vin);
swap(first.blockHash, second.blockHash);
swap(first.sigTime, second.sigTime);
swap(first.vchSig, second.vchSig);
}
CMasternodePing& operator=(CMasternodePing from)
{
swap(*this, from);
return *this;
}
friend bool operator==(const CMasternodePing& a, const CMasternodePing& b)
{
return a.vin == b.vin && a.blockHash == b.blockHash;
}
friend bool operator!=(const CMasternodePing& a, const CMasternodePing& b)
{
return !(a == b);
}
};
// //
// 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.
@ -64,9 +129,7 @@ public:
CPubKey pubkey2; CPubKey pubkey2;
std::vector<unsigned char> sig; std::vector<unsigned char> sig;
int activeState; int activeState;
int64_t sigTime; //mnb message times int64_t sigTime; //mnb message time
int64_t lastMnping;
int64_t lastTimeSeen;
int cacheInputAge; int cacheInputAge;
int cacheInputAgeBlock; int cacheInputAgeBlock;
bool unitTest; bool unitTest;
@ -76,11 +139,12 @@ public:
int nScanningErrorCount; int nScanningErrorCount;
int nLastScanningErrorBlockHeight; int nLastScanningErrorBlockHeight;
int nVotedTimes; int nVotedTimes;
CMasternodePing lastPing;
CMasternode(); CMasternode();
CMasternode(const CMasternode& other); CMasternode(const CMasternode& other);
CMasternode(const CMasternodeBroadcast& other); CMasternode(const CMasternodeBroadcast& mnb);
CMasternode(CService newAddr, CTxIn newVin, CPubKey newPubkey, std::vector<unsigned char> newSig, int64_t newSigTime, CPubKey newPubkey2, int protocolVersionIn);
void swap(CMasternode& first, CMasternode& second) // nothrow void swap(CMasternode& first, CMasternode& second) // nothrow
@ -97,8 +161,7 @@ public:
swap(first.sig, second.sig); swap(first.sig, second.sig);
swap(first.activeState, second.activeState); swap(first.activeState, second.activeState);
swap(first.sigTime, second.sigTime); swap(first.sigTime, second.sigTime);
swap(first.lastMnping, second.lastMnping); swap(first.lastPing, second.lastPing);
swap(first.lastTimeSeen, second.lastTimeSeen);
swap(first.cacheInputAge, second.cacheInputAge); swap(first.cacheInputAge, second.cacheInputAge);
swap(first.cacheInputAgeBlock, second.cacheInputAgeBlock); swap(first.cacheInputAgeBlock, second.cacheInputAgeBlock);
swap(first.unitTest, second.unitTest); swap(first.unitTest, second.unitTest);
@ -138,10 +201,9 @@ public:
READWRITE(pubkey2); READWRITE(pubkey2);
READWRITE(sig); READWRITE(sig);
READWRITE(sigTime); READWRITE(sigTime);
READWRITE(lastTimeSeen);
READWRITE(protocolVersion); READWRITE(protocolVersion);
READWRITE(activeState); READWRITE(activeState);
READWRITE(lastMnping); READWRITE(lastPing);
READWRITE(cacheInputAge); READWRITE(cacheInputAge);
READWRITE(cacheInputAgeBlock); READWRITE(cacheInputAgeBlock);
READWRITE(unitTest); READWRITE(unitTest);
@ -156,15 +218,6 @@ public:
void UpdateFromNewBroadcast(CMasternodeBroadcast& mnb); void UpdateFromNewBroadcast(CMasternodeBroadcast& mnb);
void UpdateLastSeen(int64_t override=0)
{
if(override == 0){
lastTimeSeen = GetAdjustedTime();
} else {
lastTimeSeen = override;
}
}
inline uint64_t SliceHash(uint256& hash, int slice) inline uint64_t SliceHash(uint256& hash, int slice)
{ {
uint64_t n = 0; uint64_t n = 0;
@ -174,16 +227,23 @@ public:
void Check(); void Check();
bool UpdatedWithin(int seconds) bool IsBroadcastedWithin(int seconds)
{ {
// LogPrintf("UpdatedWithin %d, %d -- %d \n", GetAdjustedTime() , lastTimeSeen, (GetAdjustedTime() - lastTimeSeen) < seconds); return (GetAdjustedTime() - sigTime) < seconds;
}
return (GetAdjustedTime() - lastTimeSeen) < seconds; bool IsPingedWithin(int seconds, int64_t now = -1)
{
now == -1 ? now = GetAdjustedTime() : now;
return (lastPing == CMasternodePing())
? false
: now - lastPing.sigTime < seconds;
} }
void Disable() void Disable()
{ {
lastTimeSeen = 0; sigTime = 0;
lastPing = CMasternodePing();
} }
bool IsEnabled() bool IsEnabled()
@ -229,12 +289,12 @@ class CMasternodeBroadcast : public CMasternode
public: public:
CMasternodeBroadcast(); CMasternodeBroadcast();
CMasternodeBroadcast(CService newAddr, CTxIn newVin, CPubKey newPubkey, CPubKey newPubkey2, int protocolVersionIn); CMasternodeBroadcast(CService newAddr, CTxIn newVin, CPubKey newPubkey, CPubKey newPubkey2, int protocolVersionIn);
CMasternodeBroadcast(const CMasternode& other); CMasternodeBroadcast(const CMasternode& mn);
bool CheckAndUpdate(int& nDoS, bool fRequested); bool CheckAndUpdate(int& nDoS);
bool CheckInputsAndAdd(int& nDos, bool fRequested); bool CheckInputsAndAdd(int& nDos);
bool Sign(CKey& keyCollateralAddress); bool Sign(CKey& keyCollateralAddress);
void Relay(bool fRequested); void Relay();
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
@ -246,8 +306,8 @@ public:
READWRITE(pubkey2); READWRITE(pubkey2);
READWRITE(sig); READWRITE(sig);
READWRITE(sigTime); READWRITE(sigTime);
READWRITE(lastTimeSeen);
READWRITE(protocolVersion); READWRITE(protocolVersion);
READWRITE(lastPing);
} }
uint256 GetHash(){ uint256 GetHash(){
@ -259,43 +319,4 @@ public:
}; };
//
// The Masternode Ping Class : Contains a different serialize method for sending pings from masternodes throughout the network
//
class CMasternodePing
{
public:
CTxIn vin;
uint256 blockHash;
std::vector<unsigned char> vchSig;
int64_t sigTime; //mnb message times
//removed stop
CMasternodePing();
CMasternodePing(CTxIn& newVin);
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(vin);
READWRITE(blockHash);
READWRITE(sigTime);
READWRITE(vchSig);
}
bool CheckAndUpdate(int& nDos);
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
void Relay();
uint256 GetHash(){
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << vin;
ss << sigTime;
return ss.GetHash();
}
};
#endif #endif

View File

@ -12,8 +12,6 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
CCriticalSection cs_process_message;
/** Masternode manager */ /** Masternode manager */
CMasternodeMan mnodeman; CMasternodeMan mnodeman;
@ -84,7 +82,7 @@ bool CMasternodeDB::Write(const CMasternodeMan& mnodemanToSave)
return true; return true;
} }
CMasternodeDB::ReadResult CMasternodeDB::Read(CMasternodeMan& mnodemanToLoad) CMasternodeDB::ReadResult CMasternodeDB::Read(CMasternodeMan& mnodemanToLoad, bool fDryRun)
{ {
int64_t nStart = GetTimeMillis(); int64_t nStart = GetTimeMillis();
// open input file, and associate with CAutoFile // open input file, and associate with CAutoFile
@ -159,9 +157,12 @@ CMasternodeDB::ReadResult CMasternodeDB::Read(CMasternodeMan& mnodemanToLoad)
return IncorrectFormat; return IncorrectFormat;
} }
mnodemanToLoad.CheckAndRemove(); // clean out expired
LogPrintf("Loaded info from mncache.dat %dms\n", GetTimeMillis() - nStart); LogPrintf("Loaded info from mncache.dat %dms\n", GetTimeMillis() - nStart);
LogPrintf(" %s\n", mnodemanToLoad.ToString()); LogPrintf(" %s\n", mnodemanToLoad.ToString());
LogPrintf("Masternode manager - cleaning....\n");
if(!fDryRun) mnodemanToLoad.CheckAndRemove(true);
LogPrintf("Masternode manager - result:\n");
LogPrintf(" %s\n", mnodemanToLoad.ToString());
return Ok; return Ok;
} }
@ -174,7 +175,7 @@ void DumpMasternodes()
CMasternodeMan tempMnodeman; CMasternodeMan tempMnodeman;
LogPrintf("Verifying mncache.dat format...\n"); LogPrintf("Verifying mncache.dat format...\n");
CMasternodeDB::ReadResult readResult = mndb.Read(tempMnodeman); CMasternodeDB::ReadResult readResult = mndb.Read(tempMnodeman, true);
// there was an error and it was not an error on file openning => do not proceed // there was an error and it was not an error on file openning => do not proceed
if (readResult == CMasternodeDB::FileError) if (readResult == CMasternodeDB::FileError)
LogPrintf("Missing masternode cache file - mncache.dat, will try to recreate\n"); LogPrintf("Missing masternode cache file - mncache.dat, will try to recreate\n");
@ -223,24 +224,22 @@ void CMasternodeMan::Check()
BOOST_FOREACH(CMasternode& mn, vMasternodes) { BOOST_FOREACH(CMasternode& mn, vMasternodes) {
mn.Check(); mn.Check();
// // if it matches our Masternode privkey, then we've been remotely activated
// if(mn.pubkey2 == activeMasternode.pubKeyMasternode && mn.protocolVersion == PROTOCOL_VERSION){
// activeMasternode.EnableHotColdMasterNode(mn.vin, mn.addr);
// }
} }
} }
void CMasternodeMan::CheckAndRemove() void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval)
{ {
LOCK(cs); LOCK(cs);
Check(); Check();
//remove inactive //remove inactive and outdated
vector<CMasternode>::iterator it = vMasternodes.begin(); vector<CMasternode>::iterator it = vMasternodes.begin();
while(it != vMasternodes.end()){ while(it != vMasternodes.end()){
if((*it).activeState == CMasternode::MASTERNODE_REMOVE || (*it).activeState == CMasternode::MASTERNODE_VIN_SPENT || (*it).protocolVersion < nMasternodeMinProtocol){ if((*it).activeState == CMasternode::MASTERNODE_REMOVE ||
(*it).activeState == CMasternode::MASTERNODE_VIN_SPENT ||
(forceExpiredRemoval && (*it).activeState == CMasternode::MASTERNODE_EXPIRED) ||
(*it).protocolVersion < nMasternodeMinProtocol) {
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 {
@ -576,14 +575,13 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
if (strCommand == "mnb") { //Masternode Broadcast if (strCommand == "mnb") { //Masternode Broadcast
CMasternodeBroadcast mnb; CMasternodeBroadcast mnb;
bool fRequested; //specifically requested? vRecv >> mnb;
vRecv >> mnb >> fRequested;
if(mapSeenMasternodeBroadcast.count(mnb.GetHash())) return; //seen if(mapSeenMasternodeBroadcast.count(mnb.GetHash())) return; //seen
mapSeenMasternodeBroadcast[mnb.GetHash()] = mnb; mapSeenMasternodeBroadcast[mnb.GetHash()] = mnb;
int nDoS = 0; int nDoS = 0;
if(!mnb.CheckAndUpdate(nDoS, fRequested)){ if(!mnb.CheckAndUpdate(nDoS)){
if(nDoS > 0) if(nDoS > 0)
Misbehaving(pfrom->GetId(), nDoS); Misbehaving(pfrom->GetId(), nDoS);
@ -600,15 +598,13 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
return; return;
} }
if(fDebug) LogPrintf("mnb - Got NEW Masternode entry %s\n", mnb.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()
if(mnb.CheckInputsAndAdd(nDoS, fRequested)) { if(mnb.CheckInputsAndAdd(nDoS)) {
// use this as a peer // use this as a peer
addrman.Add(CAddress(mnb.addr), pfrom->addr, 2*60*60); addrman.Add(CAddress(mnb.addr), pfrom->addr, 2*60*60);
} else { } else {
LogPrintf("mnb - Rejected Masternode entry %s\n", mnb.addr.ToString().c_str()); LogPrintf("mnb - Rejected Masternode entry %s\n", mnb.addr.ToString());
if (nDoS > 0) if (nDoS > 0)
Misbehaving(pfrom->GetId(), nDoS); Misbehaving(pfrom->GetId(), nDoS);
@ -619,22 +615,22 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
CMasternodePing mnp; CMasternodePing mnp;
vRecv >> mnp; vRecv >> mnp;
if(fDebug) LogPrintf("mnp - Masternode ping, vin: %s\n", mnp.vin.ToString());
if(mapSeenMasternodePing.count(mnp.GetHash())) return; //seen if(mapSeenMasternodePing.count(mnp.GetHash())) return; //seen
mapSeenMasternodePing[mnp.GetHash()] = mnp; mapSeenMasternodePing[mnp.GetHash()] = mnp;
int nDoS = 0; int nDoS = 0;
if(mnp.CheckAndUpdate(nDoS)) if(mnp.CheckAndUpdate(nDoS)) return;
{
//successful, we're done if(nDoS > 0) {
// if anything significant failed, mark that node and return
Misbehaving(pfrom->GetId(), nDoS);
return; return;
} else {
//failure
if(nDoS > 0)
Misbehaving(pfrom->GetId(), nDoS);
} }
if(fDebug) LogPrintf("mnp - Couldn't find Masternode entry %s\n", mnp.vin.ToString().c_str()); // we wasn't able to accept mnp but nothing significant happened,
// we might just have to ask for a masternode entry once
std::map<COutPoint, int64_t>::iterator i = mWeAskedForMasternodeListEntry.find(mnp.vin.prevout); std::map<COutPoint, int64_t>::iterator i = mWeAskedForMasternodeListEntry.find(mnp.vin.prevout);
if (i != mWeAskedForMasternodeListEntry.end()) if (i != mWeAskedForMasternodeListEntry.end())
{ {
@ -644,7 +640,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
// ask for the mnb info once from the node that sent mnp // ask for the mnb info once from the node that sent mnp
LogPrintf("mnp - Asking source node for missing entry %s\n", mnp.vin.ToString().c_str()); LogPrintf("mnp - Asking source node for missing entry, vin: %s\n", mnp.vin.ToString());
pfrom->PushMessage("dseg", mnp.vin); pfrom->PushMessage("dseg", mnp.vin);
int64_t askAgain = GetTime() + MASTERNODE_MIN_MNP_SECONDS; int64_t askAgain = GetTime() + MASTERNODE_MIN_MNP_SECONDS;
mWeAskedForMasternodeListEntry[mnp.vin.prevout] = askAgain; mWeAskedForMasternodeListEntry[mnp.vin.prevout] = askAgain;
@ -677,27 +673,24 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
BOOST_FOREACH(CMasternode& mn, vMasternodes) { BOOST_FOREACH(CMasternode& mn, vMasternodes) {
if(mn.addr.IsRFC1918()) continue; //local network if(mn.addr.IsRFC1918()) continue; //local network
bool fRequested = true;
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()){
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000); ss.reserve(1000);
ss << CMasternodeBroadcast(mn); ss << CMasternodeBroadcast(mn);
ss << fRequested;
pfrom->PushMessage("mnb", ss); pfrom->PushMessage("mnb", ss);
} else if (vin == mn.vin) { } else if (vin == mn.vin) {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000); ss.reserve(1000);
ss << CMasternodeBroadcast(mn); ss << CMasternodeBroadcast(mn);
ss << fRequested;
pfrom->PushMessage("mnb", ss); pfrom->PushMessage("mnb", ss);
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());

View File

@ -49,7 +49,7 @@ public:
CMasternodeDB(); CMasternodeDB();
bool Write(const CMasternodeMan &mnodemanToSave); bool Write(const CMasternodeMan &mnodemanToSave);
ReadResult Read(CMasternodeMan& mnodemanToLoad); ReadResult Read(CMasternodeMan& mnodemanToLoad, bool fDryRun = false);
}; };
class CMasternodeMan class CMasternodeMan
@ -58,6 +58,9 @@ private:
// critical section to protect the inner data structures // critical section to protect the inner data structures
mutable CCriticalSection cs; mutable CCriticalSection cs;
// critical section to protect the inner data structures specifically on messaging
mutable CCriticalSection cs_process_message;
// 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
@ -93,7 +96,7 @@ public:
void Check(); void Check();
/// Check all Masternodes and remove inactive /// Check all Masternodes and remove inactive
void CheckAndRemove(); void CheckAndRemove(bool forceExpiredRemoval = false);
/// Clear Masternode vector /// Clear Masternode vector
void Clear(); void Clear();

View File

@ -19,7 +19,6 @@
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
#include "wallet.h" #include "wallet.h"
#endif #endif
#include "masternodeman.h"
#include "masternode-payments.h" #include "masternode-payments.h"
#include <boost/thread.hpp> #include <boost/thread.hpp>

View File

@ -199,21 +199,13 @@ Value masternode(const Array& params, bool fHelp)
} }
} }
if(activeMasternode.status != MASTERNODE_REMOTELY_ENABLED && activeMasternode.status != MASTERNODE_IS_CAPABLE){ if(activeMasternode.status != MASTERNODE_STARTED){
activeMasternode.status = MASTERNODE_NOT_PROCESSED; // TODO: consider better way activeMasternode.status = MASTERNODE_INITIAL; // TODO: consider better way
std::string errorMessage;
activeMasternode.ManageStatus(); activeMasternode.ManageStatus();
pwalletMain->Lock(); pwalletMain->Lock();
} }
if(activeMasternode.status == MASTERNODE_REMOTELY_ENABLED) return "masternode started remotely"; return activeMasternode.GetStatus();
if(activeMasternode.status == MASTERNODE_INPUT_TOO_NEW) return "masternode input must have at least 15 confirmations";
if(activeMasternode.status == MASTERNODE_STOPPED) return "masternode is stopped";
if(activeMasternode.status == MASTERNODE_IS_CAPABLE) return "successfully started masternode";
if(activeMasternode.status == MASTERNODE_NOT_CAPABLE) return "not capable masternode: " + activeMasternode.notCapableReason;
if(activeMasternode.status == MASTERNODE_SYNC_IN_PROCESS) return "sync in process. Must wait until client is synced to start.";
return "unknown";
} }
if (strCommand == "start-alias") if (strCommand == "start-alias")
@ -330,12 +322,7 @@ Value masternode(const Array& params, bool fHelp)
if (strCommand == "debug") if (strCommand == "debug")
{ {
if(activeMasternode.status == MASTERNODE_REMOTELY_ENABLED) return "masternode started remotely"; if(activeMasternode.status != MASTERNODE_INITIAL) return activeMasternode.GetStatus();
if(activeMasternode.status == MASTERNODE_INPUT_TOO_NEW) return "masternode input must have at least 15 confirmations";
if(activeMasternode.status == MASTERNODE_IS_CAPABLE) return "successfully started masternode";
if(activeMasternode.status == MASTERNODE_STOPPED) return "masternode is stopped";
if(activeMasternode.status == MASTERNODE_NOT_CAPABLE) return "not capable masternode: " + activeMasternode.notCapableReason;
if(activeMasternode.status == MASTERNODE_SYNC_IN_PROCESS) return "sync in process. Must wait until client is synced to start.";
CTxIn vin = CTxIn(); CTxIn vin = CTxIn();
CPubKey pubkey = CScript(); CPubKey pubkey = CScript();
@ -369,8 +356,10 @@ Value masternode(const Array& params, bool fHelp)
obj.push_back(Pair("protocol", (int64_t)winner->protocolVersion)); obj.push_back(Pair("protocol", (int64_t)winner->protocolVersion));
obj.push_back(Pair("vin", winner->vin.prevout.hash.ToString().c_str())); obj.push_back(Pair("vin", winner->vin.prevout.hash.ToString().c_str()));
obj.push_back(Pair("pubkey", address2.ToString().c_str())); obj.push_back(Pair("pubkey", address2.ToString().c_str()));
obj.push_back(Pair("lastseen", (int64_t)winner->lastTimeSeen)); obj.push_back(Pair("lastseen", (winner->lastPing == CMasternodePing()) ? winner->sigTime :
obj.push_back(Pair("activeseconds", (int64_t)(winner->lastTimeSeen - winner->sigTime))); (int64_t)winner->lastPing.sigTime));
obj.push_back(Pair("activeseconds", (winner->lastPing == CMasternodePing()) ? 0 :
(int64_t)(winner->lastPing.sigTime - winner->sigTime)));
return obj; return obj;
} }
@ -498,6 +487,7 @@ Value masternodelist(const Array& params, bool fHelp)
" additional matches in some modes are also available\n" " additional matches in some modes are also available\n"
"\nAvailable modes:\n" "\nAvailable modes:\n"
" activeseconds - Print number of seconds masternode recognized by the network as enabled\n" " activeseconds - Print number of seconds masternode recognized by the network as enabled\n"
" (since latest issued \"masternode start/start-many/start-alias\")\n"
" full - Print info in format 'status protocol pubkey IP lastseen activeseconds lastpaid'\n" " full - Print info in format 'status protocol pubkey IP lastseen activeseconds lastpaid'\n"
" (can be additionally filtered, partial match)\n" " (can be additionally filtered, partial match)\n"
" lastseen - Print timestamp of when a masternode was last seen on the network\n" " lastseen - Print timestamp of when a masternode was last seen on the network\n"
@ -526,7 +516,7 @@ Value masternodelist(const Array& params, bool fHelp)
std::string strVin = mn.vin.prevout.ToStringShort(); std::string strVin = mn.vin.prevout.ToStringShort();
if (strMode == "activeseconds") { if (strMode == "activeseconds") {
if(strFilter !="" && strVin.find(strFilter) == string::npos) continue; if(strFilter !="" && strVin.find(strFilter) == string::npos) continue;
obj.push_back(Pair(strVin, (int64_t)(mn.lastTimeSeen - mn.sigTime))); obj.push_back(Pair(strVin, (int64_t)(mn.lastPing.sigTime - mn.sigTime)));
} else if (strMode == "full") { } else if (strMode == "full") {
CScript pubkey; CScript pubkey;
pubkey = GetScriptForDestination(mn.pubkey.GetID()); pubkey = GetScriptForDestination(mn.pubkey.GetID());
@ -543,8 +533,8 @@ Value masternodelist(const Array& params, bool fHelp)
mn.protocolVersion << " " << mn.protocolVersion << " " <<
address2.ToString() << " " << address2.ToString() << " " <<
mn.addr.ToString() << " " << mn.addr.ToString() << " " <<
mn.lastTimeSeen << " " << setw(8) << mn.lastPing.sigTime << " " << setw(8) <<
(mn.lastTimeSeen - mn.sigTime) << " " << (mn.lastPing.sigTime - mn.sigTime) << " " <<
mn.GetLastPaid(); mn.GetLastPaid();
std::string output = stringStream.str(); std::string output = stringStream.str();
stringStream << " " << strVin; stringStream << " " << strVin;
@ -553,7 +543,7 @@ Value masternodelist(const Array& params, bool fHelp)
obj.push_back(Pair(addrStream.str(), output)); obj.push_back(Pair(addrStream.str(), output));
} else if (strMode == "lastseen") { } else if (strMode == "lastseen") {
if(strFilter !="" && strVin.find(strFilter) == string::npos) continue; if(strFilter !="" && strVin.find(strFilter) == string::npos) continue;
obj.push_back(Pair(strVin, (int64_t)mn.lastTimeSeen)); obj.push_back(Pair(strVin, (int64_t)mn.lastPing.sigTime));
} else if (strMode == "protocol") { } else if (strMode == "protocol") {
if(strFilter !="" && strFilter != boost::lexical_cast<std::string>(mn.protocolVersion) && if(strFilter !="" && strFilter != boost::lexical_cast<std::string>(mn.protocolVersion) &&
strVin.find(strFilter) == string::npos) continue; strVin.find(strFilter) == string::npos) continue;

View File

@ -10,7 +10,7 @@
* network protocol versioning * network protocol versioning
*/ */
static const int PROTOCOL_VERSION = 70089; static const int PROTOCOL_VERSION = 70090;
//! initial proto version, to be increased after version/verack negotiation //! initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209; static const int INIT_PROTO_VERSION = 209;
@ -22,16 +22,16 @@ static const int GETHEADERS_VERSION = 70077;
static const int MIN_PEER_PROTO_VERSION = 70066; static const int MIN_PEER_PROTO_VERSION = 70066;
//! minimum peer version accepted by DarksendPool //! minimum peer version accepted by DarksendPool
static const int MIN_POOL_PEER_PROTO_VERSION = 70089; static const int MIN_POOL_PEER_PROTO_VERSION = 70090;
//! minimum peer version for masternode budgets //! minimum peer version for masternode budgets
static const int MIN_BUDGET_PEER_PROTO_VERSION = 70089; static const int MIN_BUDGET_PEER_PROTO_VERSION = 70090;
//! minimum peer version that can receive masternode payments //! minimum peer version that can receive masternode payments
// V1 - Last protocol version before update // V1 - Last protocol version before update
// V2 - Newest protocol version // V2 - Newest protocol version
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70066; static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70066;
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70089; static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70090;
//! nTime field added to CAddress, starting with this version; //! nTime field added to CAddress, starting with this version;
//! if possible, avoid requesting addresses nodes older than this //! if possible, avoid requesting addresses nodes older than this