dash/src/masternode.cpp

799 lines
32 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),
nActiveState(MASTERNODE_ENABLED),
nCacheCollateralBlock(0),
nBlockLastPaid(0),
nProtocolVersion(PROTOCOL_VERSION),
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),
nActiveState(MASTERNODE_ENABLED),
nCacheCollateralBlock(0),
nBlockLastPaid(0),
nProtocolVersion(nProtocolVersionIn),
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),
nActiveState(other.nActiveState),
nCacheCollateralBlock(other.nCacheCollateralBlock),
nBlockLastPaid(other.nBlockLastPaid),
nProtocolVersion(other.nProtocolVersion),
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),
nActiveState(MASTERNODE_ENABLED),
nCacheCollateralBlock(0),
nBlockLastPaid(0),
nProtocolVersion(mnb.nProtocolVersion),
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)
{
if(mnb.sigTime > sigTime) {
pubKeyMasternode = mnb.pubKeyMasternode;
2015-08-12 03:39:22 +02:00
sigTime = mnb.sigTime;
vchSig = mnb.vchSig;
nProtocolVersion = mnb.nProtocolVersion;
2015-08-12 03:39:22 +02:00
addr = mnb.addr;
nTimeLastChecked = 0;
int nDos = 0;
if(mnb.lastPing == CMasternodePing() || (mnb.lastPing != CMasternodePing() && mnb.lastPing.CheckAndUpdate(nDos, false))) {
2015-08-12 03:39:22 +02:00
lastPing = mnb.lastPing;
mnodeman.mapSeenMasternodePing.insert(std::make_pair(lastPing.GetHash(), lastPing));
2015-08-12 03:39:22 +02:00
}
return true;
}
2015-08-12 03:39:22 +02:00
return false;
}
//
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
//
uint256 CMasternode::CalculateScore(int nBlockHeight)
{
uint256 hash;
uint256 aux = ArithToUint256(UintToArith256(vin.prevout.hash) + vin.prevout.n);
if(!GetBlockHash(hash, nBlockHeight)) {
LogPrintf("CMasternode::CalculateScore -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", nBlockHeight);
return uint256();
}
2015-02-07 19:31:15 +01:00
2015-07-24 17:50:10 +02:00
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss << hash;
arith_uint256 hash2 = UintToArith256(ss.GetHash());
2015-07-24 17:50:10 +02:00
CHashWriter ss2(SER_GETHASH, PROTOCOL_VERSION);
ss2 << hash;
ss2 << aux;
arith_uint256 hash3 = UintToArith256(ss2.GetHash());
2015-02-07 19:31:15 +01:00
arith_uint256 r = (hash3 > hash2 ? hash3 - hash2 : hash2 - hash3);
2015-02-07 19:31:15 +01:00
return ArithToUint256(r);
}
void CMasternode::Check(bool fForce)
{
//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
bool fRemove = // If there were no pings for quite a long time ...
!IsPingedWithin(MASTERNODE_REMOVAL_SECONDS) ||
// or masternode doesn't meet payment protocol requirements ...
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
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
2016-09-05 18:09:25 +02:00
FlagGovernanceItemsAsDirty();
return;
}
if(!IsPingedWithin(MASTERNODE_EXPIRATION_SECONDS)) {
nActiveState = MASTERNODE_EXPIRED;
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;
}
if(lastPing.sigTime - sigTime < MASTERNODE_MIN_MNP_SECONDS) {
nActiveState = MASTERNODE_PRE_ENABLED;
return;
}
if(!fUnitTest) {
CValidationState state;
2015-04-03 00:51:08 +02:00
CMutableTransaction tx = CMutableTransaction();
2016-09-05 18:09:25 +02:00
CTxOut txout = CTxOut(999.99*COIN, mnodeman.dummyScriptPubkey);
tx.vin.push_back(vin);
2016-09-05 18:09:25 +02:00
tx.vout.push_back(txout);
2015-07-30 15:44:18 +02:00
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;
if(!AcceptToMemoryPool(mempool, state, CTransaction(tx), false, NULL, false, true, true)) {
nActiveState = MASTERNODE_OUTPOINT_SPENT;
2015-07-30 15:44:18 +02:00
return;
}
}
}
nActiveState = MASTERNODE_ENABLED; // OK
}
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";
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());
2016-09-05 18:09:25 +02:00
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
mnbRet = CMasternodeBroadcast();
return false;
}
mnbRet = CMasternodeBroadcast(service, txin, pubKeyCollateralAddressNew, pubKeyMasternodeNew, PROTOCOL_VERSION);
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;
}
bool CMasternodeBroadcast::CheckAndUpdate(int& nDos)
{
nDos = 0;
// make sure signature isn't in the future (past is OK)
if (sigTime > GetAdjustedTime() + 60 * 60) {
LogPrintf("CMasternodeBroadcast::CheckAndUpdate -- Signature rejected, too far into the future: masternode=%s\n", vin.prevout.ToStringShort());
nDos = 1;
return false;
}
// incorrect ping or its sigTime
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()) {
LogPrintf("CMasternodeBroadcast::CheckAndUpdate -- ignoring outdated Masternode: masternode=%s nProtocolVersion=%d\n", vin.prevout.ToStringShort(), nProtocolVersion);
return false;
}
CScript pubkeyScript;
pubkeyScript = GetScriptForDestination(pubKeyCollateralAddress.GetID());
if(pubkeyScript.size() != 25) {
LogPrintf("CMasternodeBroadcast::CheckAndUpdate -- pubKeyCollateralAddress has the wrong size\n");
nDos = 100;
return false;
}
CScript pubkeyScript2;
pubkeyScript2 = GetScriptForDestination(pubKeyMasternode.GetID());
if(pubkeyScript2.size() != 25) {
LogPrintf("CMasternodeBroadcast::CheckAndUpdate -- pubKeyMasternode has the wrong size\n");
nDos = 100;
return false;
}
if(!vin.scriptSig.empty()) {
LogPrintf("CMasternodeBroadcast::CheckAndUpdate -- Ignore Not Empty ScriptSig %s\n",vin.ToString());
return false;
}
if (!CheckSignature(nDos)) {
LogPrintf("CMasternodeBroadcast::CheckAndUpdate -- 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;
2015-06-23 17:40:08 +02:00
//search existing Masternode list, this is where we update existing Masternodes with new mnb broadcasts
CMasternode* pmn = mnodeman.Find(vin);
// no such masternode, nothing to update
if(pmn == NULL) return true;
// this broadcast is older or equal than the one that we already have - it's bad and should never happen
// unless someone is doing something fishy
// (mapSeenMasternodeBroadcast in CMasternodeMan::ProcessMessage should filter legit duplicates)
if(pmn->sigTime >= sigTime) {
LogPrintf("CMasternodeBroadcast::CheckAndUpdate -- Bad sigTime %d (existing broadcast is at %d) for Masternode %s %s\n",
sigTime, pmn->sigTime, vin.prevout.ToStringShort(), addr.ToString());
return false;
}
// masternode is not enabled yet/already, nothing to update
if(!pmn->IsEnabled()) return true;
// IsVnAssociatedWithPubkey is validated once below, after that they just need to match
if(pmn->pubKeyCollateralAddress == pubKeyCollateralAddress && !pmn->IsBroadcastedWithin(MASTERNODE_MIN_MNB_SECONDS)) {
//take the newest entry
LogPrintf("CMasternodeBroadcast::CheckAndUpdate -- 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;
}
bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDos)
{
// we are a masternode with the same vin (i.e. already activated) and this mnb is ours (matches our Masternode privkey)
// so nothing to do here for us
if(fMasterNode && vin.prevout == activeMasternode.vin.prevout && pubKeyMasternode == activeMasternode.pubKeyMasternode) {
return true;
}
// incorrect ping or its sigTime
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
}
// search existing Masternode list
CMasternode* pmn = mnodeman.Find(vin);
if(pmn != NULL) {
// nothing to do here if we already know about this masternode and it's (pre)enabled
if(pmn->IsEnabled() || pmn->IsPreEnabled()) return true;
// if it's not (pre)enabled, remove old MN first and continue
2016-09-05 18:09:25 +02:00
mnodeman.Remove(pmn->vin);
}
2016-09-05 18:09:25 +02:00
if(GetInputAge(vin) < Params().GetConsensus().nMasternodeMinimumConfirmations) {
LogPrintf("CMasternodeBroadcast::CheckInputsAndAdd -- Input must have at least %d confirmations\n", Params().GetConsensus().nMasternodeMinimumConfirmations);
// maybe we miss few blocks, let this mnb to be checked again later
mnodeman.mapSeenMasternodeBroadcast.erase(GetHash());
return false;
}
CValidationState state;
2016-09-05 18:09:25 +02:00
CMutableTransaction dummyTx = CMutableTransaction();
CTxOut dummyTxOut = CTxOut(999.99*COIN, mnodeman.dummyScriptPubkey);
dummyTx.vin.push_back(vin);
dummyTx.vout.push_back(dummyTxOut);
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
LogPrint("masternode", "CMasternodeBroadcast::CheckInputsAndAdd -- Failed to aquire lock, addr=%s", addr.ToString());
mnodeman.mapSeenMasternodeBroadcast.erase(GetHash());
return false;
}
2015-07-30 15:44:18 +02:00
2016-09-05 18:09:25 +02:00
if(!AcceptToMemoryPool(mempool, state, CTransaction(dummyTx), false, NULL, false, true, true)) {
2015-07-30 15:44:18 +02:00
//set nDos
2016-09-05 18:09:25 +02:00
LogPrint("masternode", "CMasternodeBroadcast::CheckInputsAndAdd -- Failed to accepted Masternode entry to mempool: dummyTx=%s", dummyTx.ToString());
state.IsInvalid(nDos);
return false;
}
2015-07-30 15:44:18 +02:00
}
2016-09-05 18:09:25 +02:00
LogPrint("masternode", "CMasternodeBroadcast::CheckInputsAndAdd -- Accepted Masternode entry to mempool (dry-run mode)\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)) {
LogPrintf("CMasternodeMan::CheckInputsAndAdd -- 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) {
LogPrintf("CMasternodeBroadcast::CheckInputsAndAdd -- 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
}
// if it matches our Masternode privkey...
if(fMasterNode && pubKeyMasternode == activeMasternode.pubKeyMasternode) {
if(nProtocolVersion == PROTOCOL_VERSION) {
// ... and PROTOCOL_VERSION, then we've been remotely activated ...
2016-09-05 18:09:25 +02:00
activeMasternode.EnableRemoteMasterNode(vin, addr);
} else {
// ... otherwise we need to reactivate our node, don not add it to the list and do not relay
// but also do not ban the node we get this message from
LogPrintf("CMasternodeBroadcast::CheckInputsAndAdd -- wrong PROTOCOL_VERSION, re-activate your MN: message nProtocolVersion=%d PROTOCOL_VERSION=%d\n", nProtocolVersion, PROTOCOL_VERSION);
return false;
}
}
LogPrintf("CMasternodeBroadcast::CheckInputsAndAdd -- Got NEW Masternode entry: masternode=%s sigTime=%lld addr=%s\n", vin.prevout.ToStringShort(), sigTime, addr.ToString());
2015-07-30 15:44:18 +02:00
CMasternode mn(*this);
mnodeman.Add(mn);
2015-07-30 15:44:18 +02:00
bool isLocal = addr.IsRFC1918() || addr.IsLocal();
2016-09-05 18:09:25 +02:00
if(Params().NetworkIDString() == CBaseChainParams::REGTEST) {
isLocal = false;
}
2015-07-30 15:44:18 +02:00
2016-09-05 18:09:25 +02:00
if(!isLocal) {
Relay();
}
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 fCheckSigTimeOnly)
{
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;
}
if (fCheckSigTimeOnly) {
CMasternode* pmn = mnodeman.Find(vin);
if (pmn) return CheckSignature(pmn->pubKeyMasternode, nDos);
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;
}
if (fRequireEnabled && !pmn->IsEnabled() && !pmn->IsPreEnabled()) 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;
{
LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(blockHash);
if (mi == mapBlockIndex.end()) {
LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode is unknown: masternode=%s blockHash=%s\n", vin.prevout.ToStringShort(), blockHash.ToString());
// maybe we stuck so we shouldn't ban this node, just fail to accept it
// TODO: or should we also request this block?
return false;
}
if ((*mi).second && (*mi).second->nHeight < chainActive.Height() - 24) {
LogPrintf("CMasternodePing::CheckAndUpdate -- Masternode 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;
}
}
// 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)
{
if(mapGovernaceObjectsVotedOn.count(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
mapGovernaceObjectsVotedOn[nGovernanceObjectHash]++;
} else {
mapGovernaceObjectsVotedOn.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
}
}
/**
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()
{
std::map<uint256, int>::iterator it = mapGovernaceObjectsVotedOn.begin();
while(it != mapGovernaceObjectsVotedOn.end()){
CGovernanceObject *pObj = governance.FindGovernanceObject((*it).first);
if(pObj) pObj->fDirtyCache = true;
++it;
}
}