Merge #922: Refactor/fix spork

42bdf42 Refactor/fix spork:
- move ProcessSpork, GetSporkValue, IsSporkActive, ExecuteSpork and mapSporksActive to CSporkManager
- move Sign, CheckSignature, Relay to CSporkMessage
- move ReprocessBlocks out of sporks to main.cpp / rename DisconnectBlocksAndReprocess to DisconnectBlocks
- rename SporkKey to SporkPubKey
- bugfix: only set strMasterPrivKey if spork signature produced by that key was verified successfully
- few log format changes, cleaned up includes
This commit is contained in:
UdjinM6 2016-07-30 15:04:27 +04:00 committed by Holger Schinzel
parent 7551d2da26
commit d514ee7f9a
11 changed files with 223 additions and 245 deletions

View File

@ -148,7 +148,7 @@ public:
fTestnetToBeDeprecatedFieldRPC = false;
nPoolMaxTransactions = 3;
strSporkKey = "04549ac134f694c0243f503e8c8a9a986f5de6610049c40b07816809b0d1d06a21b07be27b9bb555931773f62ba6cf35a25fd52f694d4e1106ccd237a7bb899fdd";
strSporkPubKey = "04549ac134f694c0243f503e8c8a9a986f5de6610049c40b07816809b0d1d06a21b07be27b9bb555931773f62ba6cf35a25fd52f694d4e1106ccd237a7bb899fdd";
strMasternodePaymentsPubKey = "04549ac134f694c0243f503e8c8a9a986f5de6610049c40b07816809b0d1d06a21b07be27b9bb555931773f62ba6cf35a25fd52f694d4e1106ccd237a7bb899fdd";
checkpointData = (CCheckpointData) {
@ -257,7 +257,7 @@ public:
fTestnetToBeDeprecatedFieldRPC = true;
nPoolMaxTransactions = 2;
strSporkKey = "046f78dcf911fbd61910136f7f0f8d90578f68d0b3ac973b5040fb7afb501b5939f39b108b0569dca71488f5bbf498d92e4d1194f6f941307ffd95f75e76869f0e";
strSporkPubKey = "046f78dcf911fbd61910136f7f0f8d90578f68d0b3ac973b5040fb7afb501b5939f39b108b0569dca71488f5bbf498d92e4d1194f6f941307ffd95f75e76869f0e";
strMasternodePaymentsPubKey = "046f78dcf911fbd61910136f7f0f8d90578f68d0b3ac973b5040fb7afb501b5939f39b108b0569dca71488f5bbf498d92e4d1194f6f941307ffd95f75e76869f0e";
checkpointData = (CCheckpointData) {
boost::assign::map_list_of

View File

@ -78,7 +78,7 @@ public:
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
int PoolMaxTransactions() const { return nPoolMaxTransactions; }
std::string SporkKey() const { return strSporkKey; }
std::string SporkPubKey() const { return strSporkPubKey; }
std::string MasternodePaymentPubKey() const { return strMasternodePaymentsPubKey; }
protected:
CChainParams() {}
@ -102,7 +102,7 @@ protected:
bool fTestnetToBeDeprecatedFieldRPC;
CCheckpointData checkpointData;
int nPoolMaxTransactions;
std::string strSporkKey;
std::string strSporkPubKey;
std::string strMasternodePaymentsPubKey;
};

View File

@ -41,7 +41,7 @@ int nCompleteTXLocks;
void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
if(fLiteMode) return; //disable all darksend/masternode related functionality
if(!IsSporkActive(SPORK_2_INSTANTX)) return;
if(!sporkManager.IsSporkActive(SPORK_2_INSTANTX)) return;
if(!masternodeSync.IsBlockchainSynced()) return;
if (strCommand == NetMsgType::IX)
@ -192,8 +192,8 @@ bool IsIXTXValid(const CTransaction& txCollateral){
}
}
if(nValueOut > GetSporkValue(SPORK_5_MAX_VALUE)*COIN){
LogPrint("instantsend", "IsIXTXValid - Transaction value too high - %s\n", txCollateral.ToString());
if(nValueOut > sporkManager.GetSporkValue(SPORK_5_MAX_VALUE)*COIN){
LogPrint("instantsend", "IsIXTXValid -- Transaction value too high: nValueOut=%d, txCollateral=%s", nValueOut, txCollateral.ToString());
return false;
}
@ -508,7 +508,7 @@ bool IsLockedIXTransaction(uint256 txHash) {
int GetTransactionLockSignatures(uint256 txHash)
{
if(fLargeWorkForkFound || fLargeWorkInvalidChainFound) return -2;
if(!IsSporkActive(SPORK_2_INSTANTX)) return -3;
if(!sporkManager.IsSporkActive(SPORK_2_INSTANTX)) return -3;
if(!fEnableInstantSend) return -1;
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(txHash);

View File

@ -2896,20 +2896,51 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
return true;
}
bool DisconnectBlocksAndReprocess(int blocks)
bool DisconnectBlocks(int blocks)
{
LOCK(cs_main);
CValidationState state;
const CChainParams& chainparams = Params();
LogPrintf("DisconnectBlocksAndReprocess: Got command to replay %d blocks\n", blocks);
LogPrintf("DisconnectBlocks -- Got command to replay %d blocks\n", blocks);
for(int i = 0; i <= blocks; i++)
DisconnectTip(state, chainparams.GetConsensus());
return true;
}
void ReprocessBlocks(int nBlocks)
{
std::map<uint256, int64_t>::iterator it = mapRejectedBlocks.begin();
while(it != mapRejectedBlocks.end()){
//use a window twice as large as is usual for the nBlocks we want to reset
if((*it).second > GetTime() - (nBlocks*60*5)) {
BlockMap::iterator mi = mapBlockIndex.find((*it).first);
if (mi != mapBlockIndex.end() && (*mi).second) {
LOCK(cs_main);
CBlockIndex* pindex = (*mi).second;
LogPrintf("ReprocessBlocks -- %s\n", (*it).first.ToString());
CValidationState state;
ReconsiderBlock(state, pindex);
}
}
++it;
}
CValidationState state;
{
LOCK(cs_main);
DisconnectBlocks(nBlocks);
}
if (state.IsValid()) {
ActivateBestChain(state, Params());
}
}
/**
* Return the tip of the chain with the most work in it, that isn't
* known to be invalid (it's however far from certain to be valid).
@ -3443,7 +3474,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
// ----------- instantX transaction scanning -----------
if(IsSporkActive(SPORK_3_INSTANTX_BLOCK_FILTERING)){
if(sporkManager.IsSporkActive(SPORK_3_INSTANTX_BLOCK_FILTERING)){
BOOST_FOREACH(const CTransaction& tx, block.vtx){
if (!tx.IsCoinBase()){
//only reject blocks when it's based on complete consensus
@ -5917,7 +5948,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
mnodeman.ProcessMessage(pfrom, strCommand, vRecv);
mnpayments.ProcessMessage(pfrom, strCommand, vRecv);
ProcessMessageInstantX(pfrom, strCommand, vRecv);
ProcessSpork(pfrom, strCommand, vRecv);
sporkManager.ProcessSpork(pfrom, strCommand, vRecv);
masternodeSync.ProcessMessage(pfrom, strCommand, vRecv);
governance.ProcessMessage(pfrom, strCommand, vRecv);
}

View File

@ -455,7 +455,8 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus
bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL);
/** Reprocess a number of blocks to try and get on the correct chain again **/
bool DisconnectBlocksAndReprocess(int blocks);
bool DisconnectBlocks(int blocks);
void ReprocessBlocks(int nBlocks);
/** Apply the effects of this block (with given index) on the UTXO set represented by coins */
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);

View File

@ -52,10 +52,10 @@ bool IsBlockValueValid(const CBlock& block, CAmount nExpectedValue){
} else { // we're synced and have data so check the budget schedule
//are these blocks even enabled
if(!IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS)){
if(!sporkManager.IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS)){
return block.vtx[0].GetValueOut() <= nExpectedValue;
}
// 12.1
// if(nHeight >= Params().GetConsensus().nBudgetPaymentsStartBlock &&
// budget.IsBudgetPaymentBlock(nHeight)){
@ -77,14 +77,14 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight)
}
//check if it's a budget block
// 12.1
// if(IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS)){
// 12.1
// if(sporkManager.IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS)){
// if(budget.IsBudgetPaymentBlock(nBlockHeight)){
// if(budget.IsTransactionValid(txNew, nBlockHeight)){
// return true;
// } else {
// LogPrintf("Invalid budget payment detected %s\n", txNew.ToString());
// if(IsSporkActive(SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT)){
// LogPrintf("Invalid budget payment detected %s", txNew.ToString());
// if(sporkManager.IsSporkActive(SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT)){
// return false;
// } else {
// LogPrintf("Budget enforcement is disabled, accepting block\n");
@ -99,8 +99,8 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight)
{
return true;
} else {
LogPrintf("Invalid mn payment detected %s\n", txNew.ToString());
if(IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)){
LogPrintf("Invalid mn payment detected %s", txNew.ToString());
if(sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)){
return false;
} else {
LogPrintf("Masternode payment enforcement is disabled, accepting block\n");
@ -118,7 +118,7 @@ void FillBlockPayee(CMutableTransaction& txNew, CAmount nFees)
if(!chainActive.Tip()) return;
// 12.1
// if(IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS) && budget.IsBudgetPaymentBlock(chainActive.Tip()->nHeight+1)){
// if(sporkManager.IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS) && budget.IsBudgetPaymentBlock(chainActive.Tip()->nHeight+1)){
// budget.FillBlockPayee(txNew, nFees);
// } else {
// mnpayments.FillBlockPayee(txNew, nFees);
@ -130,7 +130,7 @@ std::string GetRequiredPaymentsString(int nBlockHeight)
{
// 12.1 -- added triggered payments
// if(IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS) && budget.IsBudgetPaymentBlock(nBlockHeight)){
// if(sporkManager.IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS) && budget.IsBudgetPaymentBlock(nBlockHeight)){
// return budget.GetRequiredPaymentsString(nBlockHeight);
// } else {
// return mnpayments.GetRequiredPaymentsString(nBlockHeight);
@ -181,7 +181,7 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, CAmount nFe
}
int CMasternodePayments::GetMinMasternodePaymentsProto() {
return IsSporkActive(SPORK_10_MASTERNODE_PAY_UPDATED_NODES)
return sporkManager.IsSporkActive(SPORK_10_MASTERNODE_PAY_UPDATED_NODES)
? MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2
: MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1;
}

View File

@ -293,8 +293,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
CWalletTx *newTx = transaction.getTransaction();
CReserveKey *keyChange = transaction.getPossibleKeyChange();
if(recipients[0].useInstantX && total > GetSporkValue(SPORK_5_MAX_VALUE)*COIN){
Q_EMIT message(tr("Send Coins"), tr("InstantSend doesn't support sending values that high yet. Transactions are currently limited to %1 DASH.").arg(GetSporkValue(SPORK_5_MAX_VALUE)),
if(recipients[0].useInstantX && total > sporkManager.GetSporkValue(SPORK_5_MAX_VALUE)*COIN){
Q_EMIT message(tr("Send Coins"), tr("InstantSend doesn't support sending values that high yet. Transactions are currently limited to %1 DASH.").arg(sporkManager.GetSporkValue(SPORK_5_MAX_VALUE)),
CClientUIInterface::MSG_ERROR);
return TransactionCreationFailed;
}
@ -304,8 +304,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
if (fSubtractFeeFromAmount && fCreated)
transaction.reassignAmounts(nChangePosRet);
if(recipients[0].useInstantX && newTx->GetValueOut() > GetSporkValue(SPORK_5_MAX_VALUE)*COIN){
Q_EMIT message(tr("Send Coins"), tr("InstantSend doesn't support sending values that high yet. Transactions are currently limited to %1 DASH.").arg(GetSporkValue(SPORK_5_MAX_VALUE)),
if(recipients[0].useInstantX && newTx->GetValueOut() > sporkManager.GetSporkValue(SPORK_5_MAX_VALUE)*COIN){
Q_EMIT message(tr("Send Coins"), tr("InstantSend doesn't support sending values that high yet. Transactions are currently limited to %1 DASH.").arg(sporkManager.GetSporkValue(SPORK_5_MAX_VALUE)),
CClientUIInterface::MSG_ERROR);
return TransactionCreationFailed;
}

View File

@ -610,7 +610,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
}
result.push_back(Pair("masternode_payments", (int64_t)(pindexPrev->nHeight+1) > Params().GetConsensus().nMasternodePaymentsStartBlock));
result.push_back(Pair("enforce_masternode_payments", IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)));
result.push_back(Pair("enforce_masternode_payments", sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)));
return result;
}

View File

@ -236,14 +236,14 @@ UniValue spork(const UniValue& params, bool fHelp)
UniValue ret(UniValue::VOBJ);
for(int nSporkID = SPORK_START; nSporkID <= SPORK_END; nSporkID++){
if(sporkManager.GetSporkNameByID(nSporkID) != "Unknown")
ret.push_back(Pair(sporkManager.GetSporkNameByID(nSporkID), GetSporkValue(nSporkID)));
ret.push_back(Pair(sporkManager.GetSporkNameByID(nSporkID), sporkManager.GetSporkValue(nSporkID)));
}
return ret;
} else if(params.size() == 1 && params[0].get_str() == "active"){
UniValue ret(UniValue::VOBJ);
for(int nSporkID = SPORK_START; nSporkID <= SPORK_END; nSporkID++){
if(sporkManager.GetSporkNameByID(nSporkID) != "Unknown")
ret.push_back(Pair(sporkManager.GetSporkNameByID(nSporkID), IsSporkActive(nSporkID)));
ret.push_back(Pair(sporkManager.GetSporkNameByID(nSporkID), sporkManager.IsSporkActive(nSporkID)));
}
return ret;
} else if (params.size() == 2){
@ -257,7 +257,7 @@ UniValue spork(const UniValue& params, bool fHelp)
//broadcast new spork
if(sporkManager.UpdateSpork(nSporkID, nValue)){
ExecuteSpork(nSporkID, nValue);
sporkManager.ExecuteSpork(nSporkID, nValue);
return "success";
} else {
return "failure";

View File

@ -2,22 +2,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sync.h"
#include "net.h"
#include "key.h"
#include "util.h"
#include "base58.h"
#include "darksend.h"
#include "protocol.h"
#include "spork.h"
#include "main.h"
#include "governance.h"
#include "consensus/validation.h"
#include <boost/lexical_cast.hpp>
#include "spork.h"
using namespace std;
using namespace boost;
#include <boost/lexical_cast.hpp>
class CSporkMessage;
class CSporkManager;
@ -25,16 +14,14 @@ class CSporkManager;
CSporkManager sporkManager;
std::map<uint256, CSporkMessage> mapSporks;
std::map<int, CSporkMessage> mapSporksActive;
void ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
void CSporkManager::ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
if(fLiteMode) return; //disable all darksend/masternode related functionality
if(fLiteMode) return; // disable all Dash specific functionality
if (strCommand == NetMsgType::SPORK)
{
//LogPrintf("ProcessSpork::spork\n");
// LogPrintf("CSporkManager::ProcessSpork\n");
CDataStream vMsg(vRecv);
CSporkMessage spork;
vRecv >> spork;
@ -45,24 +32,24 @@ void ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
uint256 hash = spork.GetHash();
if(mapSporksActive.count(spork.nSporkID)) {
if(mapSporksActive[spork.nSporkID].nTimeSigned >= spork.nTimeSigned){
if(fDebug) LogPrintf("spork - seen %s block %d \n", hash.ToString(), chainActive.Tip()->nHeight);
if(fDebug) LogPrintf("CSporkManager::ProcessSpork -- seen %s block %d \n", hash.ToString(), chainActive.Tip()->nHeight);
return;
} else {
if(fDebug) LogPrintf("spork - got updated spork %s block %d \n", hash.ToString(), chainActive.Tip()->nHeight);
if(fDebug) LogPrintf("CSporkManager::ProcessSpork -- got updated spork %s block %d \n", hash.ToString(), chainActive.Tip()->nHeight);
}
}
LogPrintf("spork - new %s ID %d Time %d bestHeight %d\n", hash.ToString(), spork.nSporkID, spork.nValue, chainActive.Tip()->nHeight);
LogPrintf("spork -- new %s ID %d Time %d bestHeight %d\n", hash.ToString(), spork.nSporkID, spork.nValue, chainActive.Tip()->nHeight);
if(!sporkManager.CheckSignature(spork)){
LogPrintf("spork - invalid signature\n");
if(!spork.CheckSignature()){
LogPrintf("CSporkManager::ProcessSpork -- invalid signature\n");
Misbehaving(pfrom->GetId(), 100);
return;
}
mapSporks[hash] = spork;
mapSporksActive[spork.nSporkID] = spork;
sporkManager.Relay(spork);
spork.Relay();
//does a task if needed
ExecuteSpork(spork.nSporkID, spork.nValue);
@ -79,58 +66,7 @@ void ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
}
// grab the spork, otherwise say it's off
bool IsSporkActive(int nSporkID)
{
int64_t r = -1;
if(mapSporksActive.count(nSporkID)){
r = mapSporksActive[nSporkID].nValue;
} else {
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_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
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(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) r = SPORK_10_MASTERNODE_PAY_UPDATED_NODES_DEFAULT;
if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT;
if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT;
if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT;
if(r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
}
if(r == -1) r = 4070908800; //return 2099-1-1 by default
return r < GetTime();
}
// grab the value of the spork on the network, or the default
int64_t GetSporkValue(int nSporkID)
{
int64_t r = -1;
if(mapSporksActive.count(nSporkID)){
r = mapSporksActive[nSporkID].nValue;
} else {
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_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
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(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) r = SPORK_10_MASTERNODE_PAY_UPDATED_NODES_DEFAULT;
if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT;
if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT;
if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT;
if(r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
}
return r;
}
void ExecuteSpork(int nSporkID, int nValue)
void CSporkManager::ExecuteSpork(int nSporkID, int nValue)
{
// if(nSporkID == SPORK_11_RESET_BUDGET && nValue == 1){
// budget.Clear();
@ -138,124 +74,76 @@ void ExecuteSpork(int nSporkID, int nValue)
//correct fork via spork technology
if(nSporkID == SPORK_12_RECONSIDER_BLOCKS && nValue > 0) {
LogPrintf("Spork::ExecuteSpork -- Reconsider Last %d Blocks\n", nValue);
LogPrintf("CSporkManager::ExecuteSpork -- Reconsider Last %d Blocks\n", nValue);
ReprocessBlocks(nValue);
}
}
void ReprocessBlocks(int nBlocks)
{
std::map<uint256, int64_t>::iterator it = mapRejectedBlocks.begin();
while(it != mapRejectedBlocks.end()){
//use a window twice as large as is usual for the nBlocks we want to reset
if((*it).second > GetTime() - (nBlocks*60*5)) {
BlockMap::iterator mi = mapBlockIndex.find((*it).first);
if (mi != mapBlockIndex.end() && (*mi).second) {
LOCK(cs_main);
CBlockIndex* pindex = (*mi).second;
LogPrintf("ReprocessBlocks - %s\n", (*it).first.ToString());
CValidationState state;
ReconsiderBlock(state, pindex);
}
}
++it;
}
CValidationState state;
{
LOCK(cs_main);
DisconnectBlocksAndReprocess(nBlocks);
}
if (state.IsValid()) {
ActivateBestChain(state, Params());
}
}
bool CSporkManager::CheckSignature(CSporkMessage& spork)
{
//note: need to investigate why this is failing
std::string strMessage = boost::lexical_cast<std::string>(spork.nSporkID) + boost::lexical_cast<std::string>(spork.nValue) + boost::lexical_cast<std::string>(spork.nTimeSigned);
CPubKey pubkey(ParseHex(Params().SporkKey()));
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pubkey, spork.vchSig, strMessage, errorMessage)){
return false;
}
return true;
}
bool CSporkManager::Sign(CSporkMessage& spork)
{
std::string strMessage = boost::lexical_cast<std::string>(spork.nSporkID) + boost::lexical_cast<std::string>(spork.nValue) + boost::lexical_cast<std::string>(spork.nTimeSigned);
CKey key2;
CPubKey pubkey2;
std::string errorMessage = "";
if(!darkSendSigner.SetKey(strMasterPrivKey, errorMessage, key2, pubkey2))
{
LogPrintf("CMasternodePayments::Sign - ERROR: Invalid masternodeprivkey: '%s'\n", errorMessage);
return false;
}
if(!darkSendSigner.SignMessage(strMessage, errorMessage, spork.vchSig, key2)) {
LogPrintf("CMasternodePayments::Sign - Sign message failed");
return false;
}
if(!darkSendSigner.VerifyMessage(pubkey2, spork.vchSig, strMessage, errorMessage)) {
LogPrintf("CMasternodePayments::Sign - Verify message failed");
return false;
}
return true;
}
bool CSporkManager::UpdateSpork(int nSporkID, int64_t nValue)
{
CSporkMessage msg;
msg.nSporkID = nSporkID;
msg.nValue = nValue;
msg.nTimeSigned = GetTime();
CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetTime());
if(Sign(msg)){
Relay(msg);
mapSporks[msg.GetHash()] = msg;
mapSporksActive[nSporkID] = msg;
if(spork.Sign(strMasterPrivKey)){
spork.Relay();
mapSporks[spork.GetHash()] = spork;
mapSporksActive[nSporkID] = spork;
return true;
}
return false;
}
void CSporkManager::Relay(CSporkMessage& msg)
// grab the spork, otherwise say it's off
bool CSporkManager::IsSporkActive(int nSporkID)
{
CInv inv(MSG_SPORK, msg.GetHash());
RelayInv(inv);
int64_t r = -1;
if(mapSporksActive.count(nSporkID)){
r = mapSporksActive[nSporkID].nValue;
} else {
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_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
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(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) r = SPORK_10_MASTERNODE_PAY_UPDATED_NODES_DEFAULT;
if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT;
if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT;
if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT;
if(r == -1) LogPrintf("CSporkManager::IsSporkActive -- Unknown Spork %d\n", nSporkID);
}
if(r == -1) r = 4070908800; //return 2099-1-1 by default
return r < GetTime();
}
bool CSporkManager::SetPrivKey(std::string strPrivKey)
// grab the value of the spork on the network, or the default
int64_t CSporkManager::GetSporkValue(int nSporkID)
{
CSporkMessage msg;
int64_t r = -1;
// Test signing successful, proceed
strMasterPrivKey = strPrivKey;
Sign(msg);
if(CheckSignature(msg)){
LogPrintf("CSporkManager::SetPrivKey - Successfully initialized as spork signer\n");
return true;
if(mapSporksActive.count(nSporkID)){
r = mapSporksActive[nSporkID].nValue;
} else {
return false;
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_5_MAX_VALUE) r = SPORK_5_MAX_VALUE_DEFAULT;
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(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) r = SPORK_10_MASTERNODE_PAY_UPDATED_NODES_DEFAULT;
if(nSporkID == SPORK_11_RESET_BUDGET) r = SPORK_11_RESET_BUDGET_DEFAULT;
if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) r = SPORK_12_RECONSIDER_BLOCKS_DEFAULT;
if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) r = SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT;
if(r == -1) LogPrintf("CSporkManager::GetSporkValue -- Unknown Spork %d\n", nSporkID);
}
return r;
}
int CSporkManager::GetSporkIDByName(std::string strName)
@ -274,18 +162,81 @@ int CSporkManager::GetSporkIDByName(std::string strName)
return -1;
}
std::string CSporkManager::GetSporkNameByID(int id)
std::string CSporkManager::GetSporkNameByID(int nSporkID)
{
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_5_MAX_VALUE) return "SPORK_5_MAX_VALUE";
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";
if(id == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) return "SPORK_10_MASTERNODE_PAY_UPDATED_NODES";
if(id == SPORK_11_RESET_BUDGET) return "SPORK_11_RESET_BUDGET";
if(id == SPORK_12_RECONSIDER_BLOCKS) return "SPORK_12_RECONSIDER_BLOCKS";
if(id == SPORK_13_ENABLE_SUPERBLOCKS) return "SPORK_13_ENABLE_SUPERBLOCKS";
if(nSporkID == SPORK_2_INSTANTX) return "SPORK_2_INSTANTX";
if(nSporkID == SPORK_3_INSTANTX_BLOCK_FILTERING) return "SPORK_3_INSTANTX_BLOCK_FILTERING";
if(nSporkID == SPORK_5_MAX_VALUE) return "SPORK_5_MAX_VALUE";
if(nSporkID == SPORK_7_MASTERNODE_SCANNING) return "SPORK_7_MASTERNODE_SCANNING";
if(nSporkID == SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT) return "SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT";
if(nSporkID == SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT) return "SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT";
if(nSporkID == SPORK_10_MASTERNODE_PAY_UPDATED_NODES) return "SPORK_10_MASTERNODE_PAY_UPDATED_NODES";
if(nSporkID == SPORK_11_RESET_BUDGET) return "SPORK_11_RESET_BUDGET";
if(nSporkID == SPORK_12_RECONSIDER_BLOCKS) return "SPORK_12_RECONSIDER_BLOCKS";
if(nSporkID == SPORK_13_ENABLE_SUPERBLOCKS) return "SPORK_13_ENABLE_SUPERBLOCKS";
return "Unknown";
}
bool CSporkManager::SetPrivKey(std::string strPrivKey)
{
CSporkMessage spork;
spork.Sign(strMasterPrivKey);
if(spork.CheckSignature()){
// Test signing successful, proceed
LogPrintf("CSporkManager::SetPrivKey -- Successfully initialized as spork signer\n");
strMasterPrivKey = strPrivKey;
return true;
} else {
return false;
}
}
bool CSporkMessage::Sign(std::string strSignKey)
{
std::string strMessage = boost::lexical_cast<std::string>(nSporkID) + boost::lexical_cast<std::string>(nValue) + boost::lexical_cast<std::string>(nTimeSigned);
CKey key;
CPubKey pubkey;
std::string errorMessage = "";
if(!darkSendSigner.SetKey(strSignKey, errorMessage, key, pubkey)) {
LogPrintf("CSporkMessage::Sign -- ERROR: '%s'\n", errorMessage);
return false;
}
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchSig, key)) {
LogPrintf("CSporkMessage::Sign -- SignMessage() failed");
return false;
}
if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)) {
LogPrintf("CSporkMessage::Sign -- VerifyMessage() failed");
return false;
}
return true;
}
bool CSporkMessage::CheckSignature()
{
//note: need to investigate why this is failing
std::string strMessage = boost::lexical_cast<std::string>(nSporkID) + boost::lexical_cast<std::string>(nValue) + boost::lexical_cast<std::string>(nTimeSigned);
CPubKey pubkey(ParseHex(Params().SporkPubKey()));
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){
LogPrintf("CSporkMessage::CheckSignature -- VerifyMessage() failed");
return false;
}
return true;
}
void CSporkMessage::Relay()
{
CInv inv(MSG_SPORK, GetHash());
RelayInv(inv);
}

View File

@ -1,19 +1,14 @@
// Copyright (c) 2009-2012 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef SPORK_H
#define SPORK_H
#include "base58.h"
#include "hash.h"
#include "protocol.h"
#include "util.h"
#include "net.h"
#include "utilstrencodings.h"
using namespace std;
using namespace boost;
/*
Don't ever reuse these IDs for other sporks
- This would result in old clients getting confused about which spork is for what
@ -42,37 +37,35 @@ using namespace boost;
#define SPORK_11_RESET_BUDGET_DEFAULT 0
#define SPORK_12_RECONSIDER_BLOCKS_DEFAULT 0
#define SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT 4070908800 //OFF
class CSporkMessage;
class CSporkManager;
extern std::map<uint256, CSporkMessage> mapSporks;
extern std::map<int, CSporkMessage> mapSporksActive;
extern CSporkManager sporkManager;
void ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
int64_t GetSporkValue(int nSporkID);
bool IsSporkActive(int nSporkID);
void ExecuteSpork(int nSporkID, int nValue);
void ReprocessBlocks(int nBlocks);
//
// Spork Class
// Keeps track of all of the network spork settings
// Spork classes
// Keep track of all of the network spork settings
//
class CSporkMessage
{
public:
private:
std::vector<unsigned char> vchSig;
public:
int nSporkID;
int64_t nValue;
int64_t nTimeSigned;
uint256 GetHash(){
uint256 n = HashX11(BEGIN(nSporkID), END(nTimeSigned));
return n;
}
CSporkMessage(int nSporkID, int64_t nValue, int64_t nTimeSigned) : nSporkID(nSporkID), nValue(nValue), nTimeSigned(nTimeSigned) {}
CSporkMessage() : nSporkID(0), nValue(0), nTimeSigned(0) {}
uint256 GetHash() { return HashX11(BEGIN(nSporkID), END(nTimeSigned)); }
bool Sign(std::string strSignKey);
bool CheckSignature();
void Relay();
ADD_SERIALIZE_METHODS;
@ -91,20 +84,22 @@ class CSporkManager
private:
std::vector<unsigned char> vchSig;
std::string strMasterPrivKey;
std::map<int, CSporkMessage> mapSporksActive;
public:
CSporkManager() {
}
CSporkManager() {}
std::string GetSporkNameByID(int id);
int GetSporkIDByName(std::string strName);
void ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void ExecuteSpork(int nSporkID, int nValue);
bool UpdateSpork(int nSporkID, int64_t nValue);
bool SetPrivKey(std::string strPrivKey);
bool CheckSignature(CSporkMessage& spork);
bool Sign(CSporkMessage& spork);
void Relay(CSporkMessage& msg);
bool IsSporkActive(int nSporkID);
int64_t GetSporkValue(int nSporkID);
int GetSporkIDByName(std::string strName);
std::string GetSporkNameByID(int nSporkID);
bool SetPrivKey(std::string strPrivKey);
};
#endif