Complete rewrite of consensus code for mn/budget payments

- Added FindProposal and FindFinalBudget to budgeting class
- Added 2 new sporks for Proposals and Budget payment enforcement. This is outside of the decentralized code so we can turn it off if there's a problem.
- Detect budget blocks and pay correct amounts in super blocks
This commit is contained in:
Evan Duffield 2015-05-30 10:27:51 -07:00
parent bd4a7f2fad
commit eaf7b940a6
10 changed files with 208 additions and 65 deletions

View File

@ -2093,11 +2093,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart; int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001); LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->pprev->nBits, pindex->pprev->nHeight, nFees)) if(!IsBlockValueValid(block.vtx[0].GetValueOut(), GetBlockValue(pindex->pprev->nBits, pindex->pprev->nHeight, nFees))){
return state.DoS(100, return state.DoS(100,
error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)", error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)",
block.vtx[0].GetValueOut(), GetBlockValue(pindex->pprev->nBits, pindex->pprev->nHeight, nFees)), block.vtx[0].GetValueOut(), GetBlockValue(pindex->pprev->nBits, pindex->pprev->nHeight, nFees)),
REJECT_INVALID, "bad-cb-amount"); REJECT_INVALID, "bad-cb-amount");
}
if (!control.Wait()) if (!control.Wait())
return state.DoS(100, false); return state.DoS(100, false);

View File

@ -184,7 +184,7 @@ void DumpBudgets()
LogPrintf("Masternode dump finished %dms\n", GetTimeMillis() - nStart); LogPrintf("Masternode dump finished %dms\n", GetTimeMillis() - nStart);
} }
CBudgetProposal *CBudgetManager::Find(const std::string &strProposalName) CBudgetProposal *CBudgetManager::FindProposal(const std::string &strProposalName)
{ {
//find the prop with the highest yes count //find the prop with the highest yes count
@ -330,6 +330,68 @@ void CBudgetVote::Relay()
} }
} }
void CBudgetManager::FillBlockPayee(CMutableTransaction& txNew, int64_t nFees)
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
int nHighestCount = 0;
CScript payee;
int64_t nAmount = 0;
// ------- Grab The Highest Count
std::map<uint256, CFinalizedBudget>::iterator it = mapFinalizedBudgets.begin();
while(it != mapFinalizedBudgets.end())
{
CFinalizedBudget* prop = &((*it).second);
if(prop->GetVoteCount() > nHighestCount){
if(pindexPrev->nHeight+1 >= prop->GetBlockStart() && pindexPrev->nHeight+1 <= prop->GetBlockEnd()){
if(prop->GetPayeeAndAmount(pindexPrev->nHeight+1, payee, nAmount)){
nHighestCount = prop->GetVoteCount();
}
}
}
it++;
}
CAmount blockValue = GetBlockValue(pindexPrev->nBits, pindexPrev->nHeight, nFees);
//miners get the full amount on these blocks
txNew.vout[0].nValue = blockValue;
if(nHighestCount > 0){
txNew.vout.resize(2);
//these are super blocks, so their value can be much larger than normal
txNew.vout[1].scriptPubKey = payee;
txNew.vout[1].nValue = nAmount;
CTxDestination address1;
ExtractDestination(payee, address1);
CBitcoinAddress address2(address1);
LogPrintf("Budget payment to %s for %lld\n", address2.ToString().c_str(), nAmount);
}
}
bool CFinalizedBudget::GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, int64_t& nAmount)
{
uint256 nProp = GetProposalByBlock(nBlockHeight);
CBudgetProposal* prop = budget.FindProposal(nProp);
if(prop){
payee = prop->GetPayee();
nAmount = prop->GetAmount();
return true;
}
LogPrintf("GetPayeeAndAmount - Couldn't find budget! %s\n", nProp.ToString().c_str());
return false;
}
void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{ {
// lite mode is not supported // lite mode is not supported
@ -790,7 +852,7 @@ std::string CFinalizedBudget::GetProposals() {
std::string ret = "aeu"; std::string ret = "aeu";
BOOST_FOREACH(uint256& nHash, vecProposals){ BOOST_FOREACH(uint256& nHash, vecProposals){
CFinalizedBudget* prop = budget.Find(nHash); CFinalizedBudget* prop = budget.FindFinalizedBudget(nHash);
std::string token = nHash.ToString(); std::string token = nHash.ToString();
if(prop) token = prop->GetName(); if(prop) token = prop->GetName();
@ -801,7 +863,7 @@ std::string CFinalizedBudget::GetProposals() {
return ret; return ret;
} }
CFinalizedBudget *CBudgetManager::Find(uint256 nHash) CFinalizedBudget *CBudgetManager::FindFinalizedBudget(uint256 nHash)
{ {
if(mapFinalizedBudgets.count(nHash)) if(mapFinalizedBudgets.count(nHash))
return &mapFinalizedBudgets[nHash]; return &mapFinalizedBudgets[nHash];
@ -809,6 +871,13 @@ CFinalizedBudget *CBudgetManager::Find(uint256 nHash)
return NULL; return NULL;
} }
CBudgetProposal *CBudgetManager::FindProposal(uint256 nHash)
{
if(mapProposals.count(nHash))
return &mapProposals[nHash];
return NULL;
}
bool CBudgetManager::PropExists(uint256 nHash) bool CBudgetManager::PropExists(uint256 nHash)
{ {
@ -950,6 +1019,7 @@ bool CFinalizedBudget::IsValid()
//must be the correct block for payment to happen (once a month) //must be the correct block for payment to happen (once a month)
if(nBlockStart % GetBudgetPaymentCycleBlocks() != 0) return false; if(nBlockStart % GetBudgetPaymentCycleBlocks() != 0) return false;
if(GetBlockEnd() - nBlockStart > 100) return false; if(GetBlockEnd() - nBlockStart > 100) return false;
if(vecProposals.size() > 100) return false;
//make sure all prop names exist //make sure all prop names exist
BOOST_FOREACH(uint256 nHash, vecProposals){ BOOST_FOREACH(uint256 nHash, vecProposals){

View File

@ -1,5 +1,5 @@
// Copyright (c) 2014-2015 The Dash developers // Copyright (c) 2014-2015 The Dash developers
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef MASTERNODE_BUDGET_H #ifndef MASTERNODE_BUDGET_H
@ -90,8 +90,9 @@ public:
void Calculate(); void Calculate();
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void NewBlock(); void NewBlock();
CBudgetProposal *Find(const std::string &strProposalName); CBudgetProposal *FindProposal(const std::string &strProposalName);
CFinalizedBudget *Find(uint256 nHash); CBudgetProposal *FindProposal(uint256 nHash);
CFinalizedBudget *FindFinalizedBudget(uint256 nHash);
std::pair<std::string, std::string> GetVotes(std::string strProposalName); std::pair<std::string, std::string> GetVotes(std::string strProposalName);
@ -108,6 +109,7 @@ public:
bool PropExists(uint256 nHash); bool PropExists(uint256 nHash);
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight); bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
std::string GetRequiredPaymentsString(int64_t nBlockHeight); std::string GetRequiredPaymentsString(int64_t nBlockHeight);
void FillBlockPayee(CMutableTransaction& txNew, int64_t nFees);
void Clear(){ void Clear(){
printf("Not implemented\n"); printf("Not implemented\n");
@ -177,6 +179,7 @@ public:
if(i > (int)vecProposals.size()-1) return 0; if(i > (int)vecProposals.size()-1) return 0;
return vecProposals[i]; return vecProposals[i];
} }
bool GetPayeeAndAmount(int64_t nBlockHeight, CScript& payee, int64_t& nAmount);
uint256 GetHash(){ uint256 GetHash(){
/* /*

View File

@ -8,6 +8,7 @@
#include "darksend.h" #include "darksend.h"
#include "util.h" #include "util.h"
#include "sync.h" #include "sync.h"
#include "spork.h"
#include "addrman.h" #include "addrman.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -18,12 +19,44 @@ CMasternodePayments masternodePayments;
map<uint256, CMasternodePaymentWinner> mapMasternodePayeeVotes; map<uint256, CMasternodePaymentWinner> mapMasternodePayeeVotes;
map<uint256, CMasternodeBlockPayees> mapMasternodeBlocks; map<uint256, CMasternodeBlockPayees> mapMasternodeBlocks;
bool IsBlockValueValid(int64_t nBlockValue, int64_t nExpectedValue){
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return true;
//while syncing take the longest chain
if (fImporting || fReindex || pindexPrev->nHeight+1 < Checkpoints::GetTotalBlocksEstimate()) {
//super blocks will always be on these blocks, max 100 per budgeting
if(pindexPrev->nHeight+1 % GetBudgetPaymentCycleBlocks() < 100){
return true;
} else {
if(nBlockValue > nExpectedValue) return false;
}
} else { // we're synced so check the budget schedule
if(budget.IsBudgetPaymentBlock(pindexPrev->nHeight+1)){
//the value of the block is evaluated in CheckBlock
return true;
} else {
if(nBlockValue > nExpectedValue) return false;
}
}
return true;
}
bool IsBlockPayeeValid(const CTransaction& txNew, int64_t nBlockHeight) bool IsBlockPayeeValid(const CTransaction& txNew, int64_t nBlockHeight)
{ {
//check if it's a budget block //check if it's a budget block
if(budget.IsBudgetPaymentBlock(nBlockHeight)){ if(budget.IsBudgetPaymentBlock(nBlockHeight)){
if(budget.IsTransactionValid(txNew, nBlockHeight)){ if(budget.IsTransactionValid(txNew, nBlockHeight)){
return true; return true;
} else {
LogPrintf("Invalid budget payment detected %s\n", txNew.ToString().c_str());
if(IsSporkActive(SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT)){
return false;
} else {
LogPrintf("Budget enforcement is disabled, accepting block");
return true;
}
} }
} }
@ -31,11 +64,32 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int64_t nBlockHeight)
if(masternodePayments.IsTransactionValid(txNew, nBlockHeight)) if(masternodePayments.IsTransactionValid(txNew, nBlockHeight))
{ {
return true; return true;
} else {
LogPrintf("Invalid mn payment detected %s\n", txNew.ToString().c_str());
if(IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)){
return false;
} else {
LogPrintf("Masternode payment enforcement is disabled, accepting block");
return true;
}
} }
return false; return false;
} }
void FillBlockPayee(CMutableTransaction& txNew, int64_t nFees)
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
if(budget.IsBudgetPaymentBlock(pindexPrev->nHeight+1)){
budget.FillBlockPayee(txNew, nFees);
} else {
masternodePayments.FillBlockPayee(txNew, nFees);
}
}
std::string GetRequiredPaymentsString(int64_t nBlockHeight) std::string GetRequiredPaymentsString(int64_t nBlockHeight)
{ {
if(budget.IsBudgetPaymentBlock(nBlockHeight)){ if(budget.IsBudgetPaymentBlock(nBlockHeight)){
@ -45,6 +99,47 @@ std::string GetRequiredPaymentsString(int64_t nBlockHeight)
} }
} }
void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int64_t nFees)
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return;
bool hasPayment = true;
CScript payee;
//spork
if(!masternodePayments.GetBlockPayee(pindexPrev->nHeight+1, payee)){
//no masternode detected
CMasternode* winningNode = mnodeman.GetCurrentMasterNode(1);
if(winningNode){
payee = GetScriptForDestination(winningNode->pubkey.GetID());
} else {
LogPrintf("CreateNewBlock: Failed to detect masternode to pay\n");
hasPayment = false;
}
}
CAmount blockValue = GetBlockValue(pindexPrev->nBits, pindexPrev->nHeight, nFees);
CAmount masternodePayment = GetMasternodePayment(pindexPrev->nHeight+1, blockValue);
txNew.vout[0].nValue = blockValue;
if(hasPayment){
txNew.vout.resize(2);
txNew.vout[1].scriptPubKey = payee;
txNew.vout[1].nValue = masternodePayment;
txNew.vout[0].nValue -= masternodePayment;
CTxDestination address1;
ExtractDestination(payee, address1);
CBitcoinAddress address2(address1);
LogPrintf("Masternode payment to %s\n", address2.ToString().c_str());
}
}
void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{ {
if(IsInitialBlockDownload()) return; if(IsInitialBlockDownload()) return;
@ -304,13 +399,13 @@ bool CMasternodePaymentWinner::IsValid()
if(n == -1) if(n == -1)
{ {
if(fDebug) LogPrintf("CMasternodePaymentWinner::IsValid - Unknown Masternode\n"); LogPrintf("CMasternodePaymentWinner::IsValid - Unknown Masternode\n");
return false; return false;
} }
if(n > MNPAYMENTS_SIGNATURES_TOTAL) if(n > MNPAYMENTS_SIGNATURES_TOTAL)
{ {
if(fDebug) LogPrintf("CMasternodePaymentWinner::IsValid - Masternode not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, n); LogPrintf("CMasternodePaymentWinner::IsValid - Masternode not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, n);
return false; return false;
} }

View File

@ -29,6 +29,8 @@ void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDa
bool IsReferenceNode(CTxIn& vin); bool IsReferenceNode(CTxIn& vin);
bool IsBlockPayeeValid(const CTransaction& txNew, int64_t nBlockHeight); bool IsBlockPayeeValid(const CTransaction& txNew, int64_t nBlockHeight);
std::string GetRequiredPaymentsString(int64_t nBlockHeight); std::string GetRequiredPaymentsString(int64_t nBlockHeight);
bool IsBlockValueValid(int64_t nBlockValue, int64_t nExpectedValue);
void FillBlockPayee(CMutableTransaction& txNew, int64_t nFees);
class CMasternodePayee : public CTxOut class CMasternodePayee : public CTxOut
{ {
@ -194,6 +196,7 @@ public:
void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
std::string GetRequiredPaymentsString(int nBlockHeight); std::string GetRequiredPaymentsString(int nBlockHeight);
void FillBlockPayee(CMutableTransaction& txNew, int64_t nFees);
}; };

View File

@ -379,6 +379,9 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment()
//it's in the list -- so let's skip it //it's in the list -- so let's skip it
if(masternodePayments.IsScheduled(mn)) continue; if(masternodePayments.IsScheduled(mn)) continue;
//make sure it has as many confirmations as there are masternodes
if(mn.GetMasternodeInputAge() < CountEnabled()) continue;
if(pOldestMasternode == NULL || pOldestMasternode->SecondsSincePayment() < mn.SecondsSincePayment()){ if(pOldestMasternode == NULL || pOldestMasternode->SecondsSincePayment() < mn.SecondsSincePayment()){
pOldestMasternode = &mn; pOldestMasternode = &mn;
} }

View File

@ -99,7 +99,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
return NULL; return NULL;
CBlock *pblock = &pblocktemplate->block; // pointer for convenience CBlock *pblock = &pblocktemplate->block; // pointer for convenience
int payments = 1;
// -regtest only: allow overriding block.nVersion with // -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios // -blockversion=N to test forking scenarios
if (Params().MineBlocksOnDemand()) if (Params().MineBlocksOnDemand())
@ -127,9 +126,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE);
nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
// start masternode payments
bool bMasterNodePayment = GetTimeMicros() > Params().StartMasternodePayments();
// Collect memory pool transactions into the block // Collect memory pool transactions into the block
CAmount nFees = 0; CAmount nFees = 0;
@ -139,35 +135,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
const int nHeight = pindexPrev->nHeight + 1; const int nHeight = pindexPrev->nHeight + 1;
CCoinsViewCache view(pcoinsTip); CCoinsViewCache view(pcoinsTip);
if(bMasterNodePayment) {
bool hasPayment = true;
//spork
if(!masternodePayments.GetBlockPayee(pindexPrev->nHeight+1, pblock->payee)){
//no masternode detected
CMasternode* winningNode = mnodeman.GetCurrentMasterNode(1);
if(winningNode){
pblock->payee = GetScriptForDestination(winningNode->pubkey.GetID());
} else {
LogPrintf("CreateNewBlock: Failed to detect masternode to pay\n");
hasPayment = false;
}
}
if(hasPayment){
payments++;
txNew.vout.resize(payments);
txNew.vout[payments-1].scriptPubKey = pblock->payee;
txNew.vout[payments-1].nValue = 0;
CTxDestination address1;
ExtractDestination(pblock->payee, address1);
CBitcoinAddress address2(address1);
LogPrintf("Masternode payment to %s\n", address2.ToString().c_str());
}
}
// Add our coinbase tx as first transaction // Add our coinbase tx as first transaction
pblock->vtx.push_back(txNew); pblock->vtx.push_back(txNew);
pblocktemplate->vTxFees.push_back(-1); // updated at end pblocktemplate->vTxFees.push_back(-1); // updated at end
@ -351,18 +318,12 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
} }
} }
// Masternode and general budget payments
FillBlockPayee(txNew, nFees);
nLastBlockTx = nBlockTx; nLastBlockTx = nBlockTx;
nLastBlockSize = nBlockSize; nLastBlockSize = nBlockSize;
LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize);
CAmount blockValue = GetBlockValue(pindexPrev->nBits, pindexPrev->nHeight, nFees);
CAmount masternodePayment = GetMasternodePayment(pindexPrev->nHeight+1, blockValue);
//create masternode payment
if(payments > 1){
txNew.vout[payments-1].nValue = masternodePayment;
blockValue -= masternodePayment;
}
txNew.vout[0].nValue = blockValue;
// Compute final coinbase transaction. // Compute final coinbase transaction.
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;

View File

@ -248,7 +248,7 @@ Value mnbudget(const Array& params, bool fHelp)
std::string strProposalName = params[1].get_str(); std::string strProposalName = params[1].get_str();
CBudgetProposal* prop = budget.Find(strProposalName); CBudgetProposal* prop = budget.FindProposal(strProposalName);
if(prop == NULL) return "Unknown proposal name"; if(prop == NULL) return "Unknown proposal name";
@ -283,7 +283,7 @@ Value mnbudget(const Array& params, bool fHelp)
Object obj; Object obj;
CBudgetProposal* prop = budget.Find(strProposalName); CBudgetProposal* prop = budget.FindProposal(strProposalName);
if(prop == NULL) return "Unknown proposal name"; if(prop == NULL) return "Unknown proposal name";

View File

@ -81,11 +81,12 @@ bool IsSporkActive(int nSporkID)
if(mapSporksActive.count(nSporkID)){ if(mapSporksActive.count(nSporkID)){
r = mapSporksActive[nSporkID].nValue; r = mapSporksActive[nSporkID].nValue;
} else { } else {
if(nSporkID == SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT) r = SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT_DEFAULT;
if(nSporkID == SPORK_2_INSTANTX) r = SPORK_2_INSTANTX_DEFAULT; if(nSporkID == SPORK_2_INSTANTX) r = SPORK_2_INSTANTX_DEFAULT;
if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) r = SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT; if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) r = SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT;
if(nSporkID == SPORK_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT; if(nSporkID == SPORK_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
if(nSporkID == SPORK_7_MASTERNODE_SCANNING) r = SPORK_7_MASTERNODE_SCANNING; if(nSporkID == SPORK_7_MASTERNODE_SCANNING) r = SPORK_7_MASTERNODE_SCANNING;
if(nSporkID == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) r = SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT;
if(nSporkID == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) r = SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT;
if(r == 0) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID); if(r == 0) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
} }
@ -102,11 +103,12 @@ int GetSporkValue(int nSporkID)
if(mapSporksActive.count(nSporkID)){ if(mapSporksActive.count(nSporkID)){
r = mapSporksActive[nSporkID].nValue; r = mapSporksActive[nSporkID].nValue;
} else { } else {
if(nSporkID == SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT) r = SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT_DEFAULT;
if(nSporkID == SPORK_2_INSTANTX) r = SPORK_2_INSTANTX_DEFAULT; if(nSporkID == SPORK_2_INSTANTX) r = SPORK_2_INSTANTX_DEFAULT;
if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) r = SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT; if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) r = SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT;
if(nSporkID == SPORK_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT; if(nSporkID == SPORK_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
if(nSporkID == SPORK_7_MASTERNODE_SCANNING) r = SPORK_7_MASTERNODE_SCANNING; if(nSporkID == SPORK_7_MASTERNODE_SCANNING) r = SPORK_7_MASTERNODE_SCANNING_DEFAULT;
if(nSporkID == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) r = SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT_DEFAULT;
if(nSporkID == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) r = SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT_DEFAULT;
if(r == 0) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID); if(r == 0) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
} }
@ -209,22 +211,24 @@ bool CSporkManager::SetPrivKey(std::string strPrivKey)
int CSporkManager::GetSporkIDByName(std::string strName) int CSporkManager::GetSporkIDByName(std::string strName)
{ {
if(strName == "SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT") return SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT;
if(strName == "SPORK_2_INSTANTX") return SPORK_2_INSTANTX; if(strName == "SPORK_2_INSTANTX") return SPORK_2_INSTANTX;
if(strName == "SPORK_3_INSTANTX_BLOCK_FILTERING") return SPORK_3_INSTANTX_BLOCK_FILTERING; if(strName == "SPORK_3_INSTANTX_BLOCK_FILTERING") return SPORK_3_INSTANTX_BLOCK_FILTERING;
if(strName == "SPORK_5_MAX_VALUE") return SPORK_5_MAX_VALUE; if(strName == "SPORK_5_MAX_VALUE") return SPORK_5_MAX_VALUE;
if(strName == "SPORK_7_MASTERNODE_SCANNING") return SPORK_7_MASTERNODE_SCANNING; if(strName == "SPORK_7_MASTERNODE_SCANNING") return SPORK_7_MASTERNODE_SCANNING;
if(strName == "SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT") return SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT;
if(strName == "SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT") return SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT;
return -1; return -1;
} }
std::string CSporkManager::GetSporkNameByID(int id) std::string CSporkManager::GetSporkNameByID(int id)
{ {
if(id == SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT) return "SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT";
if(id == SPORK_2_INSTANTX) return "SPORK_2_INSTANTX"; if(id == SPORK_2_INSTANTX) return "SPORK_2_INSTANTX";
if(id == SPORK_3_INSTANTX_BLOCK_FILTERING) return "SPORK_3_INSTANTX_BLOCK_FILTERING"; if(id == SPORK_3_INSTANTX_BLOCK_FILTERING) return "SPORK_3_INSTANTX_BLOCK_FILTERING";
if(id == SPORK_5_MAX_VALUE) return "SPORK_5_MAX_VALUE"; if(id == SPORK_5_MAX_VALUE) return "SPORK_5_MAX_VALUE";
if(id == SPORK_7_MASTERNODE_SCANNING) return "SPORK_7_MASTERNODE_SCANNING"; if(id == SPORK_7_MASTERNODE_SCANNING) return "SPORK_7_MASTERNODE_SCANNING";
if(id == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) return "SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT";
if(id == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) return "SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT";
return "Unknown"; return "Unknown";
} }

View File

@ -19,20 +19,23 @@
using namespace std; using namespace std;
using namespace boost; using namespace boost;
// Don't ever reuse these IDs for other sporks /*
#define SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT 10000 Don't ever reuse these IDs for other sporks
- This would result in old clients getting confused about which spork is for what
*/
#define SPORK_2_INSTANTX 10001 #define SPORK_2_INSTANTX 10001
#define SPORK_3_INSTANTX_BLOCK_FILTERING 10002 #define SPORK_3_INSTANTX_BLOCK_FILTERING 10002
#define SPORK_4_NOTUSED 10003
#define SPORK_5_MAX_VALUE 10004 #define SPORK_5_MAX_VALUE 10004
#define SPORK_6_NOTUSED 10005
#define SPORK_7_MASTERNODE_SCANNING 10006 #define SPORK_7_MASTERNODE_SCANNING 10006
#define SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT 10007
#define SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT 10008
#define SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT_DEFAULT 1424217600 //2015-2-18
#define SPORK_2_INSTANTX_DEFAULT 978307200 //2001-1-1 #define SPORK_2_INSTANTX_DEFAULT 978307200 //2001-1-1
#define SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT 1424217600 //2015-2-18 #define SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT 1424217600 //2015-2-18
#define SPORK_5_MAX_VALUE_DEFAULT 1000 //1000 DASH #define SPORK_5_MAX_VALUE_DEFAULT 1000 //1000 DASH
#define SPORK_7_MASTERNODE_SCANNING_DEFAULT 978307200 //2001-1-1 #define SPORK_7_MASTERNODE_SCANNING_DEFAULT 978307200 //2001-1-1
#define SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT_DEFAULT 1434326400 //2015-6-15
#define SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT_DEFAULT 1434326400 //2015-6-15
class CSporkMessage; class CSporkMessage;
class CSporkManager; class CSporkManager;