dash/src/masternode.cpp

877 lines
35 KiB
C++
Raw Normal View History

// Copyright (c) 2014-2016 The Dash Core developers
2015-02-24 15:02:22 +01:00
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "activemasternode.h"
#include "consensus/validation.h"
#include "darksend.h"
#include "init.h"
#include "governance.h"
#include "masternode.h"
#include "masternode-payments.h"
#include "masternode-sync.h"
#include "masternodeman.h"
#include "util.h"
#include <boost/lexical_cast.hpp>
CMasternode::CMasternode() :
vin(),
addr(),
pubKeyCollateralAddress(),
pubKeyMasternode(),
lastPing(),
vchSig(),
sigTime(GetAdjustedTime()),
nLastDsq(0),
nTimeLastChecked(0),
nTimeLastPaid(0),
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
nTimeLastWatchdogVote(0),
nActiveState(MASTERNODE_ENABLED),
nCacheCollateralBlock(0),
nBlockLastPaid(0),
nProtocolVersion(PROTOCOL_VERSION),
2016-10-20 23:11:30 +02:00
nPoSeBanScore(0),
fAllowMixingTx(true),
fUnitTest(false)
{}
CMasternode::CMasternode(CService addrNew, CTxIn vinNew, CPubKey pubKeyCollateralAddressNew, CPubKey pubKeyMasternodeNew, int nProtocolVersionIn) :
vin(vinNew),
addr(addrNew),
pubKeyCollateralAddress(pubKeyCollateralAddressNew),
pubKeyMasternode(pubKeyMasternodeNew),
lastPing(),
vchSig(),
sigTime(GetAdjustedTime()),
nLastDsq(0),
nTimeLastChecked(0),
nTimeLastPaid(0),
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
nTimeLastWatchdogVote(0),
nActiveState(MASTERNODE_ENABLED),
nCacheCollateralBlock(0),
nBlockLastPaid(0),
nProtocolVersion(nProtocolVersionIn),
2016-10-20 23:11:30 +02:00
nPoSeBanScore(0),
fAllowMixingTx(true),
fUnitTest(false)
{}
CMasternode::CMasternode(const CMasternode& other) :
vin(other.vin),
addr(other.addr),
pubKeyCollateralAddress(other.pubKeyCollateralAddress),
pubKeyMasternode(other.pubKeyMasternode),
lastPing(other.lastPing),
vchSig(other.vchSig),
sigTime(other.sigTime),
nLastDsq(other.nLastDsq),
nTimeLastChecked(other.nTimeLastChecked),
nTimeLastPaid(other.nTimeLastPaid),
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
nTimeLastWatchdogVote(other.nTimeLastWatchdogVote),
nActiveState(other.nActiveState),
nCacheCollateralBlock(other.nCacheCollateralBlock),
nBlockLastPaid(other.nBlockLastPaid),
nProtocolVersion(other.nProtocolVersion),
2016-10-20 23:11:30 +02:00
nPoSeBanScore(other.nPoSeBanScore),
fAllowMixingTx(other.fAllowMixingTx),
fUnitTest(other.fUnitTest)
{}
CMasternode::CMasternode(const CMasternodeBroadcast& mnb) :
vin(mnb.vin),
addr(mnb.addr),
pubKeyCollateralAddress(mnb.pubKeyCollateralAddress),
pubKeyMasternode(mnb.pubKeyMasternode),
lastPing(mnb.lastPing),
vchSig(mnb.vchSig),
sigTime(mnb.sigTime),
nLastDsq(mnb.nLastDsq),
nTimeLastChecked(0),
nTimeLastPaid(0),
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
nTimeLastWatchdogVote(0),
nActiveState(MASTERNODE_ENABLED),
nCacheCollateralBlock(0),
nBlockLastPaid(0),
nProtocolVersion(mnb.nProtocolVersion),
2016-10-20 23:11:30 +02:00
nPoSeBanScore(0),
fAllowMixingTx(true),
fUnitTest(false)
{}
//
// When a new masternode broadcast is sent, update our information
//
2015-08-12 03:39:22 +02:00
bool CMasternode::UpdateFromNewBroadcast(CMasternodeBroadcast& mnb)
{
2016-10-20 23:11:30 +02:00
if(mnb.sigTime <= sigTime) return false;
pubKeyMasternode = mnb.pubKeyMasternode;
sigTime = mnb.sigTime;
vchSig = mnb.vchSig;
nProtocolVersion = mnb.nProtocolVersion;
addr = mnb.addr;
nPoSeBanScore = 0;
nTimeLastChecked = 0;
int nDos = 0;
if(mnb.lastPing == CMasternodePing() || (mnb.lastPing != CMasternodePing() && mnb.lastPing.CheckAndUpdate(nDos, false))) {
lastPing = mnb.lastPing;
mnodeman.mapSeenMasternodePing.insert(std::make_pair(lastPing.GetHash(), lastPing));
}
// if it matches our Masternode privkey...
if(fMasterNode && pubKeyMasternode == activeMasternode.pubKeyMasternode) {
nPoSeBanScore = -MASTERNODE_POSE_BAN_MAX_SCORE;
if(nProtocolVersion == PROTOCOL_VERSION) {
// ... and PROTOCOL_VERSION, then we've been remotely activated ...
activeMasternode.ManageState();
} else {
// ... otherwise we need to reactivate our node, do not add it to the list and do not relay
// but also do not ban the node we get this message from
LogPrintf("CMasternode::UpdateFromNewBroadcast -- wrong PROTOCOL_VERSION, re-activate your MN: message nProtocolVersion=%d PROTOCOL_VERSION=%d\n", nProtocolVersion, PROTOCOL_VERSION);
return false;
2015-08-12 03:39:22 +02:00
}
}
2016-10-20 23:11:30 +02:00
return true;
}
//
2015-03-05 09:11:56 +01:00
// 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
// and get paid this block
//
arith_uint256 CMasternode::CalculateScore(const uint256& blockHash)
{
uint256 aux = ArithToUint256(UintToArith256(vin.prevout.hash) + vin.prevout.n);
2015-07-24 17:50:10 +02:00
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << blockHash;
arith_uint256 hash2 = UintToArith256(ss.GetHash());
2015-07-24 17:50:10 +02:00
CHashWriter ss2(SER_GETHASH, PROTOCOL_VERSION);
ss2 << blockHash;
2015-07-24 17:50:10 +02:00
ss2 << aux;
arith_uint256 hash3 = UintToArith256(ss2.GetHash());
2015-02-07 19:31:15 +01:00
return (hash3 > hash2 ? hash3 - hash2 : hash2 - hash3);
}
void CMasternode::Check(bool fForce)
{
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
LOCK(cs);
2016-10-20 23:11:30 +02:00
static int64_t nTimeStart = GetTime();
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
2016-10-20 23:11:30 +02:00
LogPrint("masternode", "CMasternode::Check start -- vin %s\n", vin.prevout.ToStringShort());
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
//once spent, stop doing the checks
if(nActiveState == MASTERNODE_OUTPOINT_SPENT) return;
2015-07-03 00:09:14 +02:00
if(ShutdownRequested()) return;
if(!fForce && (GetTime() - nTimeLastChecked < MASTERNODE_CHECK_SECONDS)) return;
nTimeLastChecked = GetTime();
2015-08-08 12:36:30 +02:00
2016-10-20 23:11:30 +02:00
if(!fUnitTest) {
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
CCoins coins;
if(!pcoinsTip->GetCoins(vin.prevout.hash, coins) ||
(unsigned int)vin.prevout.n>=coins.vout.size() ||
coins.vout[vin.prevout.n].IsNull()) {
nActiveState = MASTERNODE_OUTPOINT_SPENT;
LogPrint("masternode", "CMasternode::Check -- Failed to find Masternode UTXO, masternode=%s\n", vin.prevout.ToStringShort());
return;
}
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
}
// masternode doesn't meet payment protocol requirements ...
bool fRemove = nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto() ||
// or it's our own node and we just updated it to the new protocol but we are still waiting for activation ...
(pubKeyMasternode == activeMasternode.pubKeyMasternode && nProtocolVersion < PROTOCOL_VERSION);
2015-08-08 12:36:30 +02:00
2016-10-20 23:11:30 +02:00
// keep old masternodes on start, give them a chance to receive an updated ping without removal/expiry
if(!masternodeSync.IsMasternodeListSynced()) nTimeStart = GetTime();
bool fWaitForPing = (GetTime() - nTimeStart < MASTERNODE_MIN_MNP_SECONDS);
Merge #944: V0.12.1.x governance pr - part 1 - base functionality 068c178 Added DBG macro in util.h to facilitate debugging - This macro allows debugging statements (typically printf's or cout's) to be activated or deactivated with a single comment. Uncomment the line: //#define ENABLE_DASH_DEBUG in util.h to enable debugging statements. - When commented any code wrapped with the DBG() macro will simply be removed by the preprocessor. When not commented all such wrapped statements will be present. - For maximum effectiveness it is best that util.h be the first effective include in all source files. It is also possible to enable the macro for a single file by temporarily adding #define ENABLE_DASH_DEBUG to the top of the file. - Code committed to non-development branches should always have the define commented. d125d9b V0.12.1.x -- merging trigger/generic object/superblock changes for testnet phase II - This commit contains the core governance system changes for 0.12.1. Any unrelated changes have either been removed or moved to separate commits. 120724c File mode fixes - Changed mode 0755->0644 on several source files. c7f9e11 Updated todo reminders - Added reminder to revert temporary reduction of number of votes required to trigger superblock to 1 for testing 92adc98 Made CSuperblockManager::IsValidSuperblockHeight an inline function - This is for efficiency since this function is called often and is only 1 line of code. c050ed7 Added comment explaining rationale for no LOCK(cs) in CSuperblock::IsValid dc933fe Removed unused CSuperblockManager::IsBlockValid function decec88 Moved calls to SuperblockManager::IsValidSuperblockHeight into IsSuperblockTriggered. - Since calls to the later function are always protected by the former there's no reason to keep these separate and this simplifies the code in masternode-payments.cpp. 8672885 Reestablished expected value check for non-superblocks in IsBlockValueValid b01cbe0 Changes to IsBlockValueValid to fix rpc test failure a937c76 Changed include order to allow per file activation of the DBG macro d116aa5 Fixed IsValidSuperblockHeight logic - Note this has an effect on testing because we can now only create 1 superblock per day. Devs may need to temporarily change testnet params for easier testing. 2d0c2de Convert superblock payments to CAmount - We assume that payment values in JSON are in units of DASH for consistency with other RPC functions, such as createrawtransaction. 376b833 Revert temporary testing value for nAbsVoteReq - Also ensure that number of votes required is never smaller than 1 8c89f4b Cleaned up CSuperblock error handling - Exceptions are now thrown consistently rather than using a mix of exceptions and return code checking. Exceptions are now caught only in AddNewTrigger when the CSuperblock constructor is called. Unnecessary object status members have been removed. d7c8a6b Removed utilstrencodings header - This appears to help with travis tests, for unknown reasons. c4dfc7a Fixed some minor code review issues 63c3580 Reverted locking change in miner. - This should have been done in the original PR but was overlooked. 4ab72de Fixed variable name to match common practice and bracket formatting 886a678 Improvements to vote conversion code - Replaced redundantly defined function with inclusion of governance-vote.h - Replaced magic numbers with their corresponding constant symbols 0a37966 Reordered governance message handling
2016-08-17 09:08:25 +02:00
2016-10-20 23:11:30 +02:00
if(nActiveState == MASTERNODE_POSE_BAN) {
if(IsPingedWithin(MASTERNODE_POSE_BAN_SECONDS)) {
// Still alive? Good luck with that.
return;
} else {
// It's finally dead, good...
// or did we just start our node and it's too early to decide?
fRemove = !fWaitForPing;
}
} else if(nPoSeBanScore >= MASTERNODE_POSE_BAN_MAX_SCORE) {
nActiveState = MASTERNODE_POSE_BAN;
return;
}
2016-10-20 23:11:30 +02:00
if(fRemove) {
// it should be removed from the list
nActiveState = MASTERNODE_REMOVE;
Merge #944: V0.12.1.x governance pr - part 1 - base functionality 068c178 Added DBG macro in util.h to facilitate debugging - This macro allows debugging statements (typically printf's or cout's) to be activated or deactivated with a single comment. Uncomment the line: //#define ENABLE_DASH_DEBUG in util.h to enable debugging statements. - When commented any code wrapped with the DBG() macro will simply be removed by the preprocessor. When not commented all such wrapped statements will be present. - For maximum effectiveness it is best that util.h be the first effective include in all source files. It is also possible to enable the macro for a single file by temporarily adding #define ENABLE_DASH_DEBUG to the top of the file. - Code committed to non-development branches should always have the define commented. d125d9b V0.12.1.x -- merging trigger/generic object/superblock changes for testnet phase II - This commit contains the core governance system changes for 0.12.1. Any unrelated changes have either been removed or moved to separate commits. 120724c File mode fixes - Changed mode 0755->0644 on several source files. c7f9e11 Updated todo reminders - Added reminder to revert temporary reduction of number of votes required to trigger superblock to 1 for testing 92adc98 Made CSuperblockManager::IsValidSuperblockHeight an inline function - This is for efficiency since this function is called often and is only 1 line of code. c050ed7 Added comment explaining rationale for no LOCK(cs) in CSuperblock::IsValid dc933fe Removed unused CSuperblockManager::IsBlockValid function decec88 Moved calls to SuperblockManager::IsValidSuperblockHeight into IsSuperblockTriggered. - Since calls to the later function are always protected by the former there's no reason to keep these separate and this simplifies the code in masternode-payments.cpp. 8672885 Reestablished expected value check for non-superblocks in IsBlockValueValid b01cbe0 Changes to IsBlockValueValid to fix rpc test failure a937c76 Changed include order to allow per file activation of the DBG macro d116aa5 Fixed IsValidSuperblockHeight logic - Note this has an effect on testing because we can now only create 1 superblock per day. Devs may need to temporarily change testnet params for easier testing. 2d0c2de Convert superblock payments to CAmount - We assume that payment values in JSON are in units of DASH for consistency with other RPC functions, such as createrawtransaction. 376b833 Revert temporary testing value for nAbsVoteReq - Also ensure that number of votes required is never smaller than 1 8c89f4b Cleaned up CSuperblock error handling - Exceptions are now thrown consistently rather than using a mix of exceptions and return code checking. Exceptions are now caught only in AddNewTrigger when the CSuperblock constructor is called. Unnecessary object status members have been removed. d7c8a6b Removed utilstrencodings header - This appears to help with travis tests, for unknown reasons. c4dfc7a Fixed some minor code review issues 63c3580 Reverted locking change in miner. - This should have been done in the original PR but was overlooked. 4ab72de Fixed variable name to match common practice and bracket formatting 886a678 Improvements to vote conversion code - Replaced redundantly defined function with inclusion of governance-vote.h - Replaced magic numbers with their corresponding constant symbols 0a37966 Reordered governance message handling
2016-08-17 09:08:25 +02:00
// RESCAN AFFECTED VOTES
FlagGovernanceItemsAsDirty();
return;
}
2016-10-20 23:11:30 +02:00
bool fWatchdogActive = mnodeman.IsWatchdogActive();
bool fWatchdogExpired = (fWatchdogActive && ((GetTime() - nTimeLastWatchdogVote) > MASTERNODE_WATCHDOG_MAX_SECONDS));
LogPrint("masternode", "CMasternode::Check -- vin %s, nTimeLastWatchdogVote %d, GetTime() %d, fWatchdogExpired %d\n",
vin.prevout.ToStringShort(), nTimeLastWatchdogVote, GetTime(), fWatchdogExpired);
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
2016-10-20 23:11:30 +02:00
if(fWatchdogExpired) {
nActiveState = MASTERNODE_WATCHDOG_EXPIRED;
return;
}
2016-10-20 23:11:30 +02:00
if(!fWaitForPing && !IsPingedWithin(MASTERNODE_EXPIRATION_SECONDS)) {
nActiveState = MASTERNODE_EXPIRED;
// RESCAN AFFECTED VOTES
FlagGovernanceItemsAsDirty();
return;
}
2016-10-20 23:11:30 +02:00
if(lastPing.sigTime - sigTime < MASTERNODE_MIN_MNP_SECONDS) {
nActiveState = MASTERNODE_PRE_ENABLED;
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
return;
}
nActiveState = MASTERNODE_ENABLED; // OK
}
bool CMasternode::IsValidNetAddr()
{
// TODO: regtest is fine with any addresses for now,
// should probably be a bit smarter if one day we start to implement tests for this
return Params().NetworkIDString() == CBaseChainParams::REGTEST ||
(addr.IsIPv4() && IsReachable(addr) && addr.IsRoutable());
}
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
masternode_info_t CMasternode::GetInfo()
{
masternode_info_t info;
info.vin = vin;
info.addr = addr;
info.pubKeyCollateralAddress = pubKeyCollateralAddress;
info.pubKeyMasternode = pubKeyMasternode;
info.sigTime = sigTime;
info.nLastDsq = nLastDsq;
info.nTimeLastChecked = nTimeLastChecked;
info.nTimeLastPaid = nTimeLastPaid;
info.nTimeLastWatchdogVote = nTimeLastWatchdogVote;
info.nActiveState = nActiveState;
info.nProtocolVersion = nProtocolVersion;
info.fInfoValid = true;
return info;
}
std::string CMasternode::GetStatus()
{
switch(nActiveState) {
case CMasternode::MASTERNODE_PRE_ENABLED: return "PRE_ENABLED";
case CMasternode::MASTERNODE_ENABLED: return "ENABLED";
case CMasternode::MASTERNODE_EXPIRED: return "EXPIRED";
case CMasternode::MASTERNODE_OUTPOINT_SPENT: return "OUTPOINT_SPENT";
case CMasternode::MASTERNODE_REMOVE: return "REMOVE";
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
case CMasternode::MASTERNODE_WATCHDOG_EXPIRED: return "WATCHDOG_EXPIRED";
2016-10-20 23:11:30 +02:00
case CMasternode::MASTERNODE_POSE_BAN: return "POSE_BAN";
default: return "UNKNOWN";
}
}
int CMasternode::GetCollateralAge()
{
2016-09-12 20:06:59 +02:00
int nHeight;
{
2016-09-12 20:06:59 +02:00
TRY_LOCK(cs_main, lockMain);
if(!lockMain || !chainActive.Tip()) return -1;
nHeight = chainActive.Height();
}
if (nCacheCollateralBlock == 0) {
int nInputAge = GetInputAge(vin);
if(nInputAge > 0) {
2016-09-12 20:06:59 +02:00
nCacheCollateralBlock = nHeight - nInputAge;
} else {
return nInputAge;
}
}
2016-09-12 20:06:59 +02:00
return nHeight - nCacheCollateralBlock;
}
void CMasternode::UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScanBack)
{
if(!pindex) return;
const CBlockIndex *BlockReading = pindex;
CScript mnpayee = GetScriptForDestination(pubKeyCollateralAddress.GetID());
// LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s\n", vin.prevout.ToStringShort());
LOCK(cs_mapMasternodeBlocks);
for (int i = 0; BlockReading && BlockReading->nHeight > nBlockLastPaid && i < nMaxBlocksToScanBack; i++) {
if(mnpayments.mapMasternodeBlocks.count(BlockReading->nHeight) &&
mnpayments.mapMasternodeBlocks[BlockReading->nHeight].HasPayeeWithVotes(mnpayee, 2))
{
CBlock block;
if(!ReadBlockFromDisk(block, BlockReading, Params().GetConsensus())) // shouldn't really happen
continue;
CAmount nMasternodePayment = GetMasternodePayment(BlockReading->nHeight, block.vtx[0].GetValueOut());
BOOST_FOREACH(CTxOut txout, block.vtx[0].vout)
if(mnpayee == txout.scriptPubKey && nMasternodePayment == txout.nValue) {
nBlockLastPaid = BlockReading->nHeight;
nTimeLastPaid = BlockReading->nTime;
LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- found new %d\n", vin.prevout.ToStringShort(), nBlockLastPaid);
return;
}
}
if (BlockReading->pprev == NULL) { assert(BlockReading); break; }
BlockReading = BlockReading->pprev;
}
// Last payment for this masternode wasn't found in latest mnpayments blocks
// or it was found in mnpayments blocks but wasn't found in the blockchain.
// LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- keeping old %d\n", vin.prevout.ToStringShort(), nBlockLastPaid);
}
2016-09-05 18:09:25 +02:00
bool CMasternodeBroadcast::Create(std::string strService, std::string strKeyMasternode, std::string strTxHash, std::string strOutputIndex, std::string& strErrorRet, CMasternodeBroadcast &mnbRet, bool fOffline)
{
CTxIn txin;
CPubKey pubKeyCollateralAddressNew;
CKey keyCollateralAddressNew;
CPubKey pubKeyMasternodeNew;
CKey keyMasternodeNew;
//need correct blocks to send ping
if(!fOffline && !masternodeSync.IsBlockchainSynced()) {
2016-09-05 18:09:25 +02:00
strErrorRet = "Sync in progress. Must wait until sync is complete to start Masternode";
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
return false;
}
if(!darkSendSigner.GetKeysFromSecret(strKeyMasternode, keyMasternodeNew, pubKeyMasternodeNew)) {
2016-09-05 18:09:25 +02:00
strErrorRet = strprintf("Invalid masternode key %s", strKeyMasternode);
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
return false;
}
if(!pwalletMain->GetMasternodeVinAndKeys(txin, pubKeyCollateralAddressNew, keyCollateralAddressNew, strTxHash, strOutputIndex)) {
2016-09-05 18:09:25 +02:00
strErrorRet = strprintf("Could not allocate txin %s:%s for masternode %s", strTxHash, strOutputIndex, strService);
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
return false;
}
CService service = CService(strService);
2016-09-05 18:09:25 +02:00
int mainnetDefaultPort = Params(CBaseChainParams::MAIN).GetDefaultPort();
if(Params().NetworkIDString() == CBaseChainParams::MAIN) {
if(service.GetPort() != mainnetDefaultPort) {
2016-09-05 18:09:25 +02:00
strErrorRet = strprintf("Invalid port %u for masternode %s, only %d is supported on mainnet.", service.GetPort(), strService, mainnetDefaultPort);
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
return false;
}
2016-09-05 18:09:25 +02:00
} else if (service.GetPort() == mainnetDefaultPort) {
strErrorRet = strprintf("Invalid port %u for masternode %s, %d is the only supported on mainnet.", service.GetPort(), strService, mainnetDefaultPort);
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
return false;
}
return Create(txin, CService(strService), keyCollateralAddressNew, pubKeyCollateralAddressNew, keyMasternodeNew, pubKeyMasternodeNew, strErrorRet, mnbRet);
}
bool CMasternodeBroadcast::Create(CTxIn txin, CService service, CKey keyCollateralAddressNew, CPubKey pubKeyCollateralAddressNew, CKey keyMasternodeNew, CPubKey pubKeyMasternodeNew, std::string &strErrorRet, CMasternodeBroadcast &mnbRet)
{
// wait for reindex and/or import to finish
if (fImporting || fReindex) return false;
CMasternodePing mnp(txin);
if(!mnp.Sign(keyMasternodeNew, pubKeyMasternodeNew)) {
strErrorRet = strprintf("Failed to sign ping, masternode=%s", txin.prevout.ToStringShort());
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
2016-09-05 18:09:25 +02:00
mnbRet = CMasternodeBroadcast();
return false;
}
mnbRet = CMasternodeBroadcast(service, txin, pubKeyCollateralAddressNew, pubKeyMasternodeNew, PROTOCOL_VERSION);
if(!mnbRet.IsValidNetAddr()) {
strErrorRet = strprintf("Invalid IP address, masternode=%s", txin.prevout.ToStringShort());
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
mnbRet = CMasternodeBroadcast();
return false;
}
2016-09-05 18:09:25 +02:00
mnbRet.lastPing = mnp;
if(!mnbRet.Sign(keyCollateralAddressNew)) {
strErrorRet = strprintf("Failed to sign broadcast, masternode=%s", txin.prevout.ToStringShort());
2016-09-05 18:09:25 +02:00
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
mnbRet = CMasternodeBroadcast();
return false;
}
return true;
}
2016-10-20 23:11:30 +02:00
bool CMasternodeBroadcast::SimpleCheck(int& nDos)
{
nDos = 0;
2016-10-20 23:11:30 +02:00
// make sure addr is valid
if(!IsValidNetAddr()) {
LogPrintf("CMasternodeBroadcast::SimpleCheck -- Invalid addr, rejected: masternode=%s addr=%s\n",
vin.prevout.ToStringShort(), addr.ToString());
return false;
}
// make sure signature isn't in the future (past is OK)
if (sigTime > GetAdjustedTime() + 60 * 60) {
2016-10-20 23:11:30 +02:00
LogPrintf("CMasternodeBroadcast::SimpleCheck -- Signature rejected, too far into the future: masternode=%s\n", vin.prevout.ToStringShort());
nDos = 1;
return false;
}
// empty ping or incorrect sigTime/blockhash
2016-09-05 18:09:25 +02:00
if(lastPing == CMasternodePing() || !lastPing.CheckAndUpdate(nDos, false, true)) {
return false;
2016-09-05 18:09:25 +02:00
}
if(nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto()) {
2016-10-20 23:11:30 +02:00
LogPrintf("CMasternodeBroadcast::SimpleCheck -- ignoring outdated Masternode: masternode=%s nProtocolVersion=%d\n", vin.prevout.ToStringShort(), nProtocolVersion);
return false;
}
CScript pubkeyScript;
pubkeyScript = GetScriptForDestination(pubKeyCollateralAddress.GetID());
if(pubkeyScript.size() != 25) {
2016-10-20 23:11:30 +02:00
LogPrintf("CMasternodeBroadcast::SimpleCheck -- pubKeyCollateralAddress has the wrong size\n");
nDos = 100;
return false;
}
CScript pubkeyScript2;
pubkeyScript2 = GetScriptForDestination(pubKeyMasternode.GetID());
if(pubkeyScript2.size() != 25) {
2016-10-20 23:11:30 +02:00
LogPrintf("CMasternodeBroadcast::SimpleCheck -- pubKeyMasternode has the wrong size\n");
nDos = 100;
return false;
}
if(!vin.scriptSig.empty()) {
2016-10-20 23:11:30 +02:00
LogPrintf("CMasternodeBroadcast::SimpleCheck -- Ignore Not Empty ScriptSig %s\n",vin.ToString());
return false;
}
if (!CheckSignature(nDos)) {
2016-10-20 23:11:30 +02:00
LogPrintf("CMasternodeBroadcast::SimpleCheck -- CheckSignature() failed, masternode=%s\n", vin.prevout.ToStringShort());
return false;
}
int mainnetDefaultPort = Params(CBaseChainParams::MAIN).GetDefaultPort();
if(Params().NetworkIDString() == CBaseChainParams::MAIN) {
if(addr.GetPort() != mainnetDefaultPort) return false;
} else if(addr.GetPort() == mainnetDefaultPort) return false;
2016-10-20 23:11:30 +02:00
return true;
}
2016-10-20 23:11:30 +02:00
bool CMasternodeBroadcast::Update(CMasternode* pmn, int& nDos)
{
if(pmn->sigTime == sigTime) {
// mapSeenMasternodeBroadcast in CMasternodeMan::CheckMnbAndUpdateMasternodeList should filter legit duplicates
// but this still can happen if we just started, which is ok, just do nothing here.
return true;
}
2016-10-20 23:11:30 +02:00
// this broadcast is older than the one that we already have - it's bad and should never happen
// unless someone is doing something fishy
2016-10-20 23:11:30 +02:00
if(pmn->sigTime > sigTime) {
LogPrintf("CMasternodeBroadcast::Update -- Bad sigTime %d (existing broadcast is at %d) for Masternode %s %s\n",
sigTime, pmn->sigTime, vin.prevout.ToStringShort(), addr.ToString());
return false;
}
2016-10-20 23:11:30 +02:00
pmn->Check();
// masternode is banned by PoSe
if(pmn->IsPoSeBanned()) {
LogPrintf("CMasternodeBroadcast::Update -- Banned by PoSe, masternode=%s\n", vin.prevout.ToStringShort());
return false;
}
// masternode is not enabled yet/already, nothing to update
2016-10-20 23:11:30 +02:00
if(!pmn->IsEnabled()) return false;
// IsVnAssociatedWithPubkey is validated once in CheckOutpoint, after that they just need to match
if(pmn->pubKeyCollateralAddress != pubKeyCollateralAddress) {
LogPrintf("CMasternodeMan::Update -- Got mismatched pubKeyCollateralAddress and vin\n");
nDos = 33;
return false;
}
2016-10-20 23:11:30 +02:00
// if ther was no masternode broadcast recently or if it matches our Masternode privkey...
if(!pmn->IsBroadcastedWithin(MASTERNODE_MIN_MNB_SECONDS) || (fMasterNode && pubKeyMasternode == activeMasternode.pubKeyMasternode)) {
// take the newest entry
LogPrintf("CMasternodeBroadcast::Update -- Got UPDATED Masternode entry: addr=%s\n", addr.ToString());
if(pmn->UpdateFromNewBroadcast((*this))) {
2015-08-12 03:39:22 +02:00
pmn->Check();
// normally masternode should be in pre-enabled status after update, if not - do not relay
2016-09-05 18:09:25 +02:00
if(pmn->IsPreEnabled()) {
Relay();
}
2015-08-12 03:39:22 +02:00
}
masternodeSync.AddedMasternodeList();
}
return true;
}
2016-10-20 23:11:30 +02:00
bool CMasternodeBroadcast::CheckOutpoint(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 && pubKeyMasternode == activeMasternode.pubKeyMasternode) {
return false;
2016-09-05 18:09:25 +02:00
}
2015-07-30 15:44:18 +02:00
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) {
// not mnb fault, let it to be checked again later
2016-10-20 23:11:30 +02:00
LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Failed to aquire lock, addr=%s", addr.ToString());
mnodeman.mapSeenMasternodeBroadcast.erase(GetHash());
return false;
}
2015-07-30 15:44:18 +02:00
2016-10-20 23:11:30 +02:00
CCoins coins;
if(!pcoinsTip->GetCoins(vin.prevout.hash, coins) ||
(unsigned int)vin.prevout.n>=coins.vout.size() ||
coins.vout[vin.prevout.n].IsNull()) {
LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Failed to find Masternode UTXO, masternode=%s\n", vin.prevout.ToStringShort());
return false;
}
if(coins.vout[vin.prevout.n].nValue != 1000 * COIN) {
LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO should have 1000 DASH, masternode=%s\n", vin.prevout.ToStringShort());
return false;
}
if(chainActive.Height() - coins.nHeight + 1 < Params().GetConsensus().nMasternodeMinimumConfirmations) {
LogPrintf("CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO must have at least %d confirmations, masternode=%s\n",
2016-10-20 23:11:30 +02:00
Params().GetConsensus().nMasternodeMinimumConfirmations, vin.prevout.ToStringShort());
// maybe we miss few blocks, let this mnb to be checked again later
mnodeman.mapSeenMasternodeBroadcast.erase(GetHash());
return false;
}
2015-07-30 15:44:18 +02:00
}
2016-10-20 23:11:30 +02:00
LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO verified\n");
// 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
if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubKeyCollateralAddress)) {
2016-10-20 23:11:30 +02:00
LogPrintf("CMasternodeMan::CheckOutpoint -- Got mismatched pubKeyCollateralAddress and vin\n");
nDos = 33;
2015-07-30 15:44:18 +02:00
return false;
}
2015-07-30 15:44:18 +02:00
// verify that sig time is legit in past
// should be at least not earlier than block when 1000 DASH tx got nMasternodeMinimumConfirmations
uint256 hashBlock = uint256();
2015-07-30 15:44:18 +02:00
CTransaction tx2;
GetTransaction(vin.prevout.hash, tx2, Params().GetConsensus(), hashBlock, true);
2015-07-30 15:44:18 +02:00
{
LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
2016-09-05 18:09:25 +02:00
if (mi != mapBlockIndex.end() && (*mi).second) {
CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation
CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + Params().GetConsensus().nMasternodeMinimumConfirmations - 1]; // block where tx got nMasternodeMinimumConfirmations
if(pConfIndex->GetBlockTime() > sigTime) {
2016-10-20 23:11:30 +02:00
LogPrintf("CMasternodeBroadcast::CheckOutpoint -- Bad sigTime %d (%d conf block is at %d) for Masternode %s %s\n",
sigTime, Params().GetConsensus().nMasternodeMinimumConfirmations, pConfIndex->GetBlockTime(), vin.prevout.ToStringShort(), addr.ToString());
return false;
}
}
2015-07-30 15:44:18 +02:00
}
2015-07-30 15:44:18 +02:00
return true;
}
bool CMasternodeBroadcast::Sign(CKey& keyCollateralAddress)
{
std::string strError;
std::string strMessage;
sigTime = GetAdjustedTime();
strMessage = addr.ToString(false) + boost::lexical_cast<std::string>(sigTime) +
pubKeyCollateralAddress.GetID().ToString() + pubKeyMasternode.GetID().ToString() +
boost::lexical_cast<std::string>(nProtocolVersion);
if(!darkSendSigner.SignMessage(strMessage, vchSig, keyCollateralAddress)) {
LogPrintf("CMasternodeBroadcast::Sign -- SignMessage() failed\n");
return false;
}
if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)) {
LogPrintf("CMasternodeBroadcast::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false;
}
return true;
}
bool CMasternodeBroadcast::CheckSignature(int& nDos)
{
std::string strMessage;
std::string strError = "";
nDos = 0;
//
// REMOVE AFTER MIGRATION TO 12.1
//
if(nProtocolVersion < 70201) {
std::string vchPubkeyCollateralAddress(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
std::string vchPubkeyMasternode(pubKeyMasternode.begin(), pubKeyMasternode.end());
strMessage = addr.ToString(false) + boost::lexical_cast<std::string>(sigTime) +
vchPubkeyCollateralAddress + vchPubkeyMasternode + boost::lexical_cast<std::string>(nProtocolVersion);
LogPrint("masternode", "CMasternodeBroadcast::CheckSignature -- sanitized strMessage: %s pubKeyCollateralAddress address: %s sig: %s\n",
SanitizeString(strMessage), CBitcoinAddress(pubKeyCollateralAddress.GetID()).ToString(),
EncodeBase64(&vchSig[0], vchSig.size()));
if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)) {
if(addr.ToString() != addr.ToString(false)) {
// maybe it's wrong format, try again with the old one
strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) +
vchPubkeyCollateralAddress + vchPubkeyMasternode + boost::lexical_cast<std::string>(nProtocolVersion);
LogPrint("masternode", "CMasternodeBroadcast::CheckSignature -- second try, sanitized strMessage: %s pubKeyCollateralAddress address: %s sig: %s\n",
SanitizeString(strMessage), CBitcoinAddress(pubKeyCollateralAddress.GetID()).ToString(),
EncodeBase64(&vchSig[0], vchSig.size()));
if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)) {
// didn't work either
LogPrintf("CMasternodeBroadcast::CheckSignature -- Got bad Masternode announce signature, second try, sanitized error: %s\n",
SanitizeString(strError));
// don't ban for old masternodes, their sigs could be broken because of the bug
return false;
}
} else {
// nope, sig is actually wrong
LogPrintf("CMasternodeBroadcast::CheckSignature -- Got bad Masternode announce signature, sanitized error: %s\n",
SanitizeString(strError));
// don't ban for old masternodes, their sigs could be broken because of the bug
return false;
}
}
} else {
//
// END REMOVE
//
strMessage = addr.ToString(false) + boost::lexical_cast<std::string>(sigTime) +
pubKeyCollateralAddress.GetID().ToString() + pubKeyMasternode.GetID().ToString() +
boost::lexical_cast<std::string>(nProtocolVersion);
LogPrint("masternode", "CMasternodeBroadcast::CheckSignature -- strMessage: %s pubKeyCollateralAddress address: %s sig: %s\n", strMessage, CBitcoinAddress(pubKeyCollateralAddress.GetID()).ToString(), EncodeBase64(&vchSig[0], vchSig.size()));
if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)){
LogPrintf("CMasternodeBroadcast::CheckSignature -- Got bad Masternode announce signature, error: %s\n", strError);
nDos = 100;
return false;
}
}
return true;
}
void CMasternodeBroadcast::Relay()
{
CInv inv(MSG_MASTERNODE_ANNOUNCE, GetHash());
RelayInv(inv);
}
CMasternodePing::CMasternodePing(CTxIn& vinNew)
{
LOCK(cs_main);
if (!chainActive.Tip() || chainActive.Height() < 12) return;
vin = vinNew;
blockHash = chainActive[chainActive.Height() - 12]->GetBlockHash();
sigTime = GetAdjustedTime();
vchSig = std::vector<unsigned char>();
}
bool CMasternodePing::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
{
std::string strError;
std::string strMasterNodeSignMessage;
sigTime = GetAdjustedTime();
std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime);
if(!darkSendSigner.SignMessage(strMessage, vchSig, keyMasternode)) {
LogPrintf("CMasternodePing::Sign -- SignMessage() failed\n");
return false;
}
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CMasternodePing::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false;
}
return true;
}
bool CMasternodePing::CheckSignature(CPubKey& pubKeyMasternode, int &nDos)
{
std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime);
std::string strError = "";
nDos = 0;
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CMasternodePing::CheckSignature -- Got bad Masternode ping signature, masternode=%s, error: %s\n", vin.prevout.ToStringShort(), strError);
nDos = 33;
return false;
}
return true;
}
bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled, bool fSimpleCheck)
{
if (sigTime > GetAdjustedTime() + 60 * 60) {
LogPrintf("CMasternodePing::CheckAndUpdate -- Signature rejected, too far into the future, masternode=%s\n", vin.prevout.ToStringShort());
nDos = 1;
return false;
}
if (sigTime <= GetAdjustedTime() - 60 * 60) {
LogPrintf("CMasternodePing::CheckAndUpdate -- Signature rejected, too far into the past: masternode=%s sigTime=%d GetAdjustedTime()=%d\n", vin.prevout.ToStringShort(), sigTime, GetAdjustedTime());
nDos = 1;
return false;
}
{
LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(blockHash);
if (mi == mapBlockIndex.end()) {
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping is invalid, unknown block hash: masternode=%s blockHash=%s\n", vin.prevout.ToStringShort(), blockHash.ToString());
// maybe we stuck or forked so we shouldn't ban this node, just fail to accept this ping
// TODO: or should we also request this block?
return false;
}
if ((*mi).second && (*mi).second->nHeight < chainActive.Height() - 24) {
LogPrintf("CMasternodePing::CheckAndUpdate -- Masternode ping is invalid, block hash is too old: masternode=%s blockHash=%s\n", vin.prevout.ToStringShort(), blockHash.ToString());
// Do nothing here (no Masternode update, no mnping relay)
// Let this node to be visible but fail to accept mnping
return false;
}
}
if (fSimpleCheck) {
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- ping verified in fSimpleCheck mode: masternode=%s blockHash=%s sigTime=%d\n", vin.prevout.ToStringShort(), blockHash.ToString(), sigTime);
return true;
}
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- New ping: masternode=%s blockHash=%s sigTime=%d\n", vin.prevout.ToStringShort(), blockHash.ToString(), sigTime);
2015-07-20 20:43:10 +02:00
// see if we have this Masternode
CMasternode* pmn = mnodeman.Find(vin);
if (pmn == NULL || pmn->nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto()) {
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Couldn't find compatible Masternode entry, masternode=%s\n", vin.prevout.ToStringShort());
return false;
}
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
if (fRequireEnabled && !pmn->IsEnabled() && !pmn->IsPreEnabled() && !pmn->IsWatchdogExpired()) return false;
// LogPrintf("mnping - Found corresponding mn for vin: %s\n", vin.prevout.ToStringShort());
// update only if there is no known ping for this masternode or
// last ping was more then MASTERNODE_MIN_MNP_SECONDS-60 ago comparing to this one
if (pmn->IsPingedWithin(MASTERNODE_MIN_MNP_SECONDS - 60, sigTime)) {
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping arrived too early, masternode=%s\n", vin.prevout.ToStringShort());
//nDos = 1; //disable, this is happening frequently and causing banned peers
return false;
}
if (!CheckSignature(pmn->pubKeyMasternode, nDos)) return false;
// so, ping seems to be ok, let's store it
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping accepted, masternode=%s\n", vin.prevout.ToStringShort());
pmn->lastPing = *this;
// and update mnodeman.mapSeenMasternodeBroadcast.lastPing which is probably outdated
CMasternodeBroadcast mnb(*pmn);
uint256 hash = mnb.GetHash();
if (mnodeman.mapSeenMasternodeBroadcast.count(hash)) {
mnodeman.mapSeenMasternodeBroadcast[hash].lastPing = *this;
}
pmn->Check(true); // force update, ignoring cache
if (!pmn->IsEnabled()) return false;
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping acceepted and relayed, masternode=%s\n", vin.prevout.ToStringShort());
Relay();
return true;
}
void CMasternodePing::Relay()
{
CInv inv(MSG_MASTERNODE_PING, GetHash());
2015-07-08 02:37:23 +02:00
RelayInv(inv);
}
Merge #944: V0.12.1.x governance pr - part 1 - base functionality 068c178 Added DBG macro in util.h to facilitate debugging - This macro allows debugging statements (typically printf's or cout's) to be activated or deactivated with a single comment. Uncomment the line: //#define ENABLE_DASH_DEBUG in util.h to enable debugging statements. - When commented any code wrapped with the DBG() macro will simply be removed by the preprocessor. When not commented all such wrapped statements will be present. - For maximum effectiveness it is best that util.h be the first effective include in all source files. It is also possible to enable the macro for a single file by temporarily adding #define ENABLE_DASH_DEBUG to the top of the file. - Code committed to non-development branches should always have the define commented. d125d9b V0.12.1.x -- merging trigger/generic object/superblock changes for testnet phase II - This commit contains the core governance system changes for 0.12.1. Any unrelated changes have either been removed or moved to separate commits. 120724c File mode fixes - Changed mode 0755->0644 on several source files. c7f9e11 Updated todo reminders - Added reminder to revert temporary reduction of number of votes required to trigger superblock to 1 for testing 92adc98 Made CSuperblockManager::IsValidSuperblockHeight an inline function - This is for efficiency since this function is called often and is only 1 line of code. c050ed7 Added comment explaining rationale for no LOCK(cs) in CSuperblock::IsValid dc933fe Removed unused CSuperblockManager::IsBlockValid function decec88 Moved calls to SuperblockManager::IsValidSuperblockHeight into IsSuperblockTriggered. - Since calls to the later function are always protected by the former there's no reason to keep these separate and this simplifies the code in masternode-payments.cpp. 8672885 Reestablished expected value check for non-superblocks in IsBlockValueValid b01cbe0 Changes to IsBlockValueValid to fix rpc test failure a937c76 Changed include order to allow per file activation of the DBG macro d116aa5 Fixed IsValidSuperblockHeight logic - Note this has an effect on testing because we can now only create 1 superblock per day. Devs may need to temporarily change testnet params for easier testing. 2d0c2de Convert superblock payments to CAmount - We assume that payment values in JSON are in units of DASH for consistency with other RPC functions, such as createrawtransaction. 376b833 Revert temporary testing value for nAbsVoteReq - Also ensure that number of votes required is never smaller than 1 8c89f4b Cleaned up CSuperblock error handling - Exceptions are now thrown consistently rather than using a mix of exceptions and return code checking. Exceptions are now caught only in AddNewTrigger when the CSuperblock constructor is called. Unnecessary object status members have been removed. d7c8a6b Removed utilstrencodings header - This appears to help with travis tests, for unknown reasons. c4dfc7a Fixed some minor code review issues 63c3580 Reverted locking change in miner. - This should have been done in the original PR but was overlooked. 4ab72de Fixed variable name to match common practice and bracket formatting 886a678 Improvements to vote conversion code - Replaced redundantly defined function with inclusion of governance-vote.h - Replaced magic numbers with their corresponding constant symbols 0a37966 Reordered governance message handling
2016-08-17 09:08:25 +02:00
void CMasternode::AddGovernanceVote(uint256 nGovernanceObjectHash)
{
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
if(mapGovernanceObjectsVotedOn.count(nGovernanceObjectHash)) {
mapGovernanceObjectsVotedOn[nGovernanceObjectHash]++;
Merge #944: V0.12.1.x governance pr - part 1 - base functionality 068c178 Added DBG macro in util.h to facilitate debugging - This macro allows debugging statements (typically printf's or cout's) to be activated or deactivated with a single comment. Uncomment the line: //#define ENABLE_DASH_DEBUG in util.h to enable debugging statements. - When commented any code wrapped with the DBG() macro will simply be removed by the preprocessor. When not commented all such wrapped statements will be present. - For maximum effectiveness it is best that util.h be the first effective include in all source files. It is also possible to enable the macro for a single file by temporarily adding #define ENABLE_DASH_DEBUG to the top of the file. - Code committed to non-development branches should always have the define commented. d125d9b V0.12.1.x -- merging trigger/generic object/superblock changes for testnet phase II - This commit contains the core governance system changes for 0.12.1. Any unrelated changes have either been removed or moved to separate commits. 120724c File mode fixes - Changed mode 0755->0644 on several source files. c7f9e11 Updated todo reminders - Added reminder to revert temporary reduction of number of votes required to trigger superblock to 1 for testing 92adc98 Made CSuperblockManager::IsValidSuperblockHeight an inline function - This is for efficiency since this function is called often and is only 1 line of code. c050ed7 Added comment explaining rationale for no LOCK(cs) in CSuperblock::IsValid dc933fe Removed unused CSuperblockManager::IsBlockValid function decec88 Moved calls to SuperblockManager::IsValidSuperblockHeight into IsSuperblockTriggered. - Since calls to the later function are always protected by the former there's no reason to keep these separate and this simplifies the code in masternode-payments.cpp. 8672885 Reestablished expected value check for non-superblocks in IsBlockValueValid b01cbe0 Changes to IsBlockValueValid to fix rpc test failure a937c76 Changed include order to allow per file activation of the DBG macro d116aa5 Fixed IsValidSuperblockHeight logic - Note this has an effect on testing because we can now only create 1 superblock per day. Devs may need to temporarily change testnet params for easier testing. 2d0c2de Convert superblock payments to CAmount - We assume that payment values in JSON are in units of DASH for consistency with other RPC functions, such as createrawtransaction. 376b833 Revert temporary testing value for nAbsVoteReq - Also ensure that number of votes required is never smaller than 1 8c89f4b Cleaned up CSuperblock error handling - Exceptions are now thrown consistently rather than using a mix of exceptions and return code checking. Exceptions are now caught only in AddNewTrigger when the CSuperblock constructor is called. Unnecessary object status members have been removed. d7c8a6b Removed utilstrencodings header - This appears to help with travis tests, for unknown reasons. c4dfc7a Fixed some minor code review issues 63c3580 Reverted locking change in miner. - This should have been done in the original PR but was overlooked. 4ab72de Fixed variable name to match common practice and bracket formatting 886a678 Improvements to vote conversion code - Replaced redundantly defined function with inclusion of governance-vote.h - Replaced magic numbers with their corresponding constant symbols 0a37966 Reordered governance message handling
2016-08-17 09:08:25 +02:00
} else {
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
mapGovernanceObjectsVotedOn.insert(std::make_pair(nGovernanceObjectHash, 1));
Merge #944: V0.12.1.x governance pr - part 1 - base functionality 068c178 Added DBG macro in util.h to facilitate debugging - This macro allows debugging statements (typically printf's or cout's) to be activated or deactivated with a single comment. Uncomment the line: //#define ENABLE_DASH_DEBUG in util.h to enable debugging statements. - When commented any code wrapped with the DBG() macro will simply be removed by the preprocessor. When not commented all such wrapped statements will be present. - For maximum effectiveness it is best that util.h be the first effective include in all source files. It is also possible to enable the macro for a single file by temporarily adding #define ENABLE_DASH_DEBUG to the top of the file. - Code committed to non-development branches should always have the define commented. d125d9b V0.12.1.x -- merging trigger/generic object/superblock changes for testnet phase II - This commit contains the core governance system changes for 0.12.1. Any unrelated changes have either been removed or moved to separate commits. 120724c File mode fixes - Changed mode 0755->0644 on several source files. c7f9e11 Updated todo reminders - Added reminder to revert temporary reduction of number of votes required to trigger superblock to 1 for testing 92adc98 Made CSuperblockManager::IsValidSuperblockHeight an inline function - This is for efficiency since this function is called often and is only 1 line of code. c050ed7 Added comment explaining rationale for no LOCK(cs) in CSuperblock::IsValid dc933fe Removed unused CSuperblockManager::IsBlockValid function decec88 Moved calls to SuperblockManager::IsValidSuperblockHeight into IsSuperblockTriggered. - Since calls to the later function are always protected by the former there's no reason to keep these separate and this simplifies the code in masternode-payments.cpp. 8672885 Reestablished expected value check for non-superblocks in IsBlockValueValid b01cbe0 Changes to IsBlockValueValid to fix rpc test failure a937c76 Changed include order to allow per file activation of the DBG macro d116aa5 Fixed IsValidSuperblockHeight logic - Note this has an effect on testing because we can now only create 1 superblock per day. Devs may need to temporarily change testnet params for easier testing. 2d0c2de Convert superblock payments to CAmount - We assume that payment values in JSON are in units of DASH for consistency with other RPC functions, such as createrawtransaction. 376b833 Revert temporary testing value for nAbsVoteReq - Also ensure that number of votes required is never smaller than 1 8c89f4b Cleaned up CSuperblock error handling - Exceptions are now thrown consistently rather than using a mix of exceptions and return code checking. Exceptions are now caught only in AddNewTrigger when the CSuperblock constructor is called. Unnecessary object status members have been removed. d7c8a6b Removed utilstrencodings header - This appears to help with travis tests, for unknown reasons. c4dfc7a Fixed some minor code review issues 63c3580 Reverted locking change in miner. - This should have been done in the original PR but was overlooked. 4ab72de Fixed variable name to match common practice and bracket formatting 886a678 Improvements to vote conversion code - Replaced redundantly defined function with inclusion of governance-vote.h - Replaced magic numbers with their corresponding constant symbols 0a37966 Reordered governance message handling
2016-08-17 09:08:25 +02:00
}
}
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
void CMasternode::RemoveGovernanceObject(uint256 nGovernanceObjectHash)
{
std::map<uint256, int>::iterator it = mapGovernanceObjectsVotedOn.find(nGovernanceObjectHash);
if(it == mapGovernanceObjectsVotedOn.end()) {
return;
}
mapGovernanceObjectsVotedOn.erase(it);
}
void CMasternode::UpdateWatchdogVoteTime()
{
LOCK(cs);
nTimeLastWatchdogVote = GetTime();
}
/**
Merge #944: V0.12.1.x governance pr - part 1 - base functionality 068c178 Added DBG macro in util.h to facilitate debugging - This macro allows debugging statements (typically printf's or cout's) to be activated or deactivated with a single comment. Uncomment the line: //#define ENABLE_DASH_DEBUG in util.h to enable debugging statements. - When commented any code wrapped with the DBG() macro will simply be removed by the preprocessor. When not commented all such wrapped statements will be present. - For maximum effectiveness it is best that util.h be the first effective include in all source files. It is also possible to enable the macro for a single file by temporarily adding #define ENABLE_DASH_DEBUG to the top of the file. - Code committed to non-development branches should always have the define commented. d125d9b V0.12.1.x -- merging trigger/generic object/superblock changes for testnet phase II - This commit contains the core governance system changes for 0.12.1. Any unrelated changes have either been removed or moved to separate commits. 120724c File mode fixes - Changed mode 0755->0644 on several source files. c7f9e11 Updated todo reminders - Added reminder to revert temporary reduction of number of votes required to trigger superblock to 1 for testing 92adc98 Made CSuperblockManager::IsValidSuperblockHeight an inline function - This is for efficiency since this function is called often and is only 1 line of code. c050ed7 Added comment explaining rationale for no LOCK(cs) in CSuperblock::IsValid dc933fe Removed unused CSuperblockManager::IsBlockValid function decec88 Moved calls to SuperblockManager::IsValidSuperblockHeight into IsSuperblockTriggered. - Since calls to the later function are always protected by the former there's no reason to keep these separate and this simplifies the code in masternode-payments.cpp. 8672885 Reestablished expected value check for non-superblocks in IsBlockValueValid b01cbe0 Changes to IsBlockValueValid to fix rpc test failure a937c76 Changed include order to allow per file activation of the DBG macro d116aa5 Fixed IsValidSuperblockHeight logic - Note this has an effect on testing because we can now only create 1 superblock per day. Devs may need to temporarily change testnet params for easier testing. 2d0c2de Convert superblock payments to CAmount - We assume that payment values in JSON are in units of DASH for consistency with other RPC functions, such as createrawtransaction. 376b833 Revert temporary testing value for nAbsVoteReq - Also ensure that number of votes required is never smaller than 1 8c89f4b Cleaned up CSuperblock error handling - Exceptions are now thrown consistently rather than using a mix of exceptions and return code checking. Exceptions are now caught only in AddNewTrigger when the CSuperblock constructor is called. Unnecessary object status members have been removed. d7c8a6b Removed utilstrencodings header - This appears to help with travis tests, for unknown reasons. c4dfc7a Fixed some minor code review issues 63c3580 Reverted locking change in miner. - This should have been done in the original PR but was overlooked. 4ab72de Fixed variable name to match common practice and bracket formatting 886a678 Improvements to vote conversion code - Replaced redundantly defined function with inclusion of governance-vote.h - Replaced magic numbers with their corresponding constant symbols 0a37966 Reordered governance message handling
2016-08-17 09:08:25 +02:00
* FLAG GOVERNANCE ITEMS AS DIRTY
*
* - When masternode come and go on the network, we must flag the items they voted on to recalc it's cached flags
*
*/
void CMasternode::FlagGovernanceItemsAsDirty()
{
V0.12.1.x sentinel watchdog pr (#1079) Squashed: * Replaced unsafe mnodeman.Find function with Get in governance-vote.cpp * Reject unparsable governance objects * Implemented sentinel watchdog objects (separated out from locking changes) * Added WATCHDOG support to rpcgovernance.cpp * Implemented WATCHDOG_EXPIRED state for masternodes * Added serialization of watchdog timestamps * Masternode fixes - Added version check to CMasternodeMan deserialization - Added several missing locking calls in CMasternodeMan * Fixed missing member initialization in CMasternode constructor and added more logging * Added MASTERNODE_WATCHDOG_MAX_SECONDS to governanceinfo * Added masternodewatchdogmaxseconds info to getgovernanceinfo help * Make masternodes remain in WATCHDOG_EXPIRED state unless removed or collateral expires * Allow watchdog object creation by WATCHDOG_EXPIRED MN * Fixed MN validation logic for governance object creation * Count total masternodes instead of enabled masternodes in masternode-sync * Transition out of WATCHDOG_EXPIRED state if the watchdog is inactive * Fixed IsWatchdogExpired bug * Fixed rate check for watchdog objects and no longer check MN state when validating governance objects * Applied PR #1061 patch * Ported locking changes from other branch * Require only 1 block between new watchdog objects * Accept pings for WATCHDOG_EXPIRED masternodes * Lock CmasternodeMan::cs in CmasternodeMan::ProcessMessage * Several governance changes - Fixed uninitialized value in CGovernancePayment class - Return an error on submission if any superblock payment cannot be parsed - Added logging more statements * Explicitly initialize all governance object members * Fix deadlock * Fixed non-threadsafe access to masternode in activemasternode.cpp * Revert added wallet lock * Changed CActiveMasternode so that watchdog expired nodes can still send pings * Modified CActiveMasternode to run pinger regardless of state when MN is in list * Added voter and time information to getvotes command * Improved CActiveMasternode state management * Implemented GetInfo functions for more efficient thread-safe access to masternode information * Added CActiveMasternode debug logging messages * Fixed initial type setting and error message for incorrect protocol version * Changes based on code review comments * Set active state for local mode
2016-10-17 20:54:28 +02:00
std::vector<uint256> vecDirty;
{
std::map<uint256, int>::iterator it = mapGovernanceObjectsVotedOn.begin();
while(it != mapGovernanceObjectsVotedOn.end()) {
vecDirty.push_back(it->first);
++it;
}
}
for(size_t i = 0; i < vecDirty.size(); ++i) {
mnodeman.AddDirtyGovernanceObjectHash(vecDirty[i]);
Merge #944: V0.12.1.x governance pr - part 1 - base functionality 068c178 Added DBG macro in util.h to facilitate debugging - This macro allows debugging statements (typically printf's or cout's) to be activated or deactivated with a single comment. Uncomment the line: //#define ENABLE_DASH_DEBUG in util.h to enable debugging statements. - When commented any code wrapped with the DBG() macro will simply be removed by the preprocessor. When not commented all such wrapped statements will be present. - For maximum effectiveness it is best that util.h be the first effective include in all source files. It is also possible to enable the macro for a single file by temporarily adding #define ENABLE_DASH_DEBUG to the top of the file. - Code committed to non-development branches should always have the define commented. d125d9b V0.12.1.x -- merging trigger/generic object/superblock changes for testnet phase II - This commit contains the core governance system changes for 0.12.1. Any unrelated changes have either been removed or moved to separate commits. 120724c File mode fixes - Changed mode 0755->0644 on several source files. c7f9e11 Updated todo reminders - Added reminder to revert temporary reduction of number of votes required to trigger superblock to 1 for testing 92adc98 Made CSuperblockManager::IsValidSuperblockHeight an inline function - This is for efficiency since this function is called often and is only 1 line of code. c050ed7 Added comment explaining rationale for no LOCK(cs) in CSuperblock::IsValid dc933fe Removed unused CSuperblockManager::IsBlockValid function decec88 Moved calls to SuperblockManager::IsValidSuperblockHeight into IsSuperblockTriggered. - Since calls to the later function are always protected by the former there's no reason to keep these separate and this simplifies the code in masternode-payments.cpp. 8672885 Reestablished expected value check for non-superblocks in IsBlockValueValid b01cbe0 Changes to IsBlockValueValid to fix rpc test failure a937c76 Changed include order to allow per file activation of the DBG macro d116aa5 Fixed IsValidSuperblockHeight logic - Note this has an effect on testing because we can now only create 1 superblock per day. Devs may need to temporarily change testnet params for easier testing. 2d0c2de Convert superblock payments to CAmount - We assume that payment values in JSON are in units of DASH for consistency with other RPC functions, such as createrawtransaction. 376b833 Revert temporary testing value for nAbsVoteReq - Also ensure that number of votes required is never smaller than 1 8c89f4b Cleaned up CSuperblock error handling - Exceptions are now thrown consistently rather than using a mix of exceptions and return code checking. Exceptions are now caught only in AddNewTrigger when the CSuperblock constructor is called. Unnecessary object status members have been removed. d7c8a6b Removed utilstrencodings header - This appears to help with travis tests, for unknown reasons. c4dfc7a Fixed some minor code review issues 63c3580 Reverted locking change in miner. - This should have been done in the original PR but was overlooked. 4ab72de Fixed variable name to match common practice and bracket formatting 886a678 Improvements to vote conversion code - Replaced redundantly defined function with inclusion of governance-vote.h - Replaced magic numbers with their corresponding constant symbols 0a37966 Reordered governance message handling
2016-08-17 09:08:25 +02:00
}
}