Refactor sporks to get rid of repeated if/else blocks (#2946)
* Use enum to define spork IDs * Introduce CSporkDef and remove if/else blocks in GetSporkIDByName/GetSporkNameByID * Deduplicate code in IsSporkActive * Fix spork RPC to use new spork defs This also removes the need for SPORK_START/SPORK_END * Move sporkManager global variable below sporkDefs This ensures correct order of initialization.
This commit is contained in:
parent
a149ca7471
commit
fc73b4d6e6
@ -253,16 +253,14 @@ UniValue spork(const JSONRPCRequest& request)
|
||||
std:: string strCommand = request.params[0].get_str();
|
||||
if (strCommand == "show") {
|
||||
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), sporkManager.GetSporkValue(nSporkID)));
|
||||
for (const auto& sporkDef : sporkDefs) {
|
||||
ret.push_back(Pair(sporkDef.name, sporkManager.GetSporkValue(sporkDef.sporkId)));
|
||||
}
|
||||
return ret;
|
||||
} else if(strCommand == "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), sporkManager.IsSporkActive(nSporkID)));
|
||||
for (const auto& sporkDef : sporkDefs) {
|
||||
ret.push_back(Pair(sporkDef.name, sporkManager.IsSporkActive(sporkDef.sporkId)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -291,8 +289,8 @@ UniValue spork(const JSONRPCRequest& request)
|
||||
+ HelpExampleRpc("spork", "\"show\""));
|
||||
} else {
|
||||
// advanced mode, update spork values
|
||||
int nSporkID = sporkManager.GetSporkIDByName(request.params[0].get_str());
|
||||
if(nSporkID == -1)
|
||||
SporkId nSporkID = sporkManager.GetSporkIDByName(request.params[0].get_str());
|
||||
if(nSporkID == SPORK_INVALID)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid spork name");
|
||||
|
||||
if (!g_connman)
|
||||
|
111
src/spork.cpp
111
src/spork.cpp
@ -13,25 +13,34 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
CSporkManager sporkManager;
|
||||
|
||||
const std::string CSporkManager::SERIALIZATION_VERSION_STRING = "CSporkManager-Version-2";
|
||||
|
||||
std::map<int, int64_t> mapSporkDefaults = {
|
||||
{SPORK_2_INSTANTSEND_ENABLED, 0}, // ON
|
||||
{SPORK_3_INSTANTSEND_BLOCK_FILTERING, 0}, // ON
|
||||
{SPORK_5_INSTANTSEND_MAX_VALUE, 1000}, // 1000 Dash
|
||||
{SPORK_6_NEW_SIGS, 4070908800ULL}, // OFF
|
||||
{SPORK_9_SUPERBLOCKS_ENABLED, 4070908800ULL}, // OFF
|
||||
{SPORK_12_RECONSIDER_BLOCKS, 0}, // 0 BLOCKS
|
||||
{SPORK_15_DETERMINISTIC_MNS_ENABLED, 4070908800ULL}, // OFF
|
||||
{SPORK_16_INSTANTSEND_AUTOLOCKS, 4070908800ULL}, // OFF
|
||||
{SPORK_17_QUORUM_DKG_ENABLED, 4070908800ULL}, // OFF
|
||||
{SPORK_19_CHAINLOCKS_ENABLED, 4070908800ULL}, // OFF
|
||||
{SPORK_20_INSTANTSEND_LLMQ_BASED, 4070908800ULL}, // OFF
|
||||
#define MAKE_SPORK_DEF(name, defaultValue) CSporkDef{name, defaultValue, #name}
|
||||
std::vector<CSporkDef> sporkDefs = {
|
||||
MAKE_SPORK_DEF(SPORK_2_INSTANTSEND_ENABLED, 0), // ON
|
||||
MAKE_SPORK_DEF(SPORK_3_INSTANTSEND_BLOCK_FILTERING, 0), // ON
|
||||
MAKE_SPORK_DEF(SPORK_5_INSTANTSEND_MAX_VALUE, 1000), // 1000 Dash
|
||||
MAKE_SPORK_DEF(SPORK_6_NEW_SIGS, 4070908800ULL), // OFF
|
||||
MAKE_SPORK_DEF(SPORK_9_SUPERBLOCKS_ENABLED, 4070908800ULL), // OFF
|
||||
MAKE_SPORK_DEF(SPORK_12_RECONSIDER_BLOCKS, 0), // 0 BLOCKS
|
||||
MAKE_SPORK_DEF(SPORK_15_DETERMINISTIC_MNS_ENABLED, 4070908800ULL), // OFF
|
||||
MAKE_SPORK_DEF(SPORK_16_INSTANTSEND_AUTOLOCKS, 4070908800ULL), // OFF
|
||||
MAKE_SPORK_DEF(SPORK_17_QUORUM_DKG_ENABLED, 4070908800ULL), // OFF
|
||||
MAKE_SPORK_DEF(SPORK_19_CHAINLOCKS_ENABLED, 4070908800ULL), // OFF
|
||||
MAKE_SPORK_DEF(SPORK_20_INSTANTSEND_LLMQ_BASED, 4070908800ULL), // OFF
|
||||
};
|
||||
|
||||
bool CSporkManager::SporkValueIsActive(int nSporkID, int64_t &nActiveValueRet) const
|
||||
CSporkManager sporkManager;
|
||||
|
||||
CSporkManager::CSporkManager()
|
||||
{
|
||||
for (auto& sporkDef : sporkDefs) {
|
||||
sporkDefsById.emplace(sporkDef.sporkId, &sporkDef);
|
||||
sporkDefsByName.emplace(sporkDef.name, &sporkDef);
|
||||
}
|
||||
}
|
||||
|
||||
bool CSporkManager::SporkValueIsActive(SporkId nSporkID, int64_t &nActiveValueRet) const
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
@ -192,7 +201,7 @@ void CSporkManager::ProcessSpork(CNode* pfrom, const std::string& strCommand, CD
|
||||
|
||||
}
|
||||
|
||||
void CSporkManager::ExecuteSpork(int nSporkID, int nValue)
|
||||
void CSporkManager::ExecuteSpork(SporkId nSporkID, int nValue)
|
||||
{
|
||||
//correct fork via spork technology
|
||||
if(nSporkID == SPORK_12_RECONSIDER_BLOCKS && nValue > 0) {
|
||||
@ -221,7 +230,7 @@ void CSporkManager::ExecuteSpork(int nSporkID, int nValue)
|
||||
}
|
||||
}
|
||||
|
||||
bool CSporkManager::UpdateSpork(int nSporkID, int64_t nValue, CConnman& connman)
|
||||
bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& connman)
|
||||
{
|
||||
CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetAdjustedTime());
|
||||
|
||||
@ -244,24 +253,13 @@ bool CSporkManager::UpdateSpork(int nSporkID, int64_t nValue, CConnman& connman)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSporkManager::IsSporkActive(int nSporkID)
|
||||
bool CSporkManager::IsSporkActive(SporkId nSporkID)
|
||||
{
|
||||
LOCK(cs);
|
||||
int64_t nSporkValue = -1;
|
||||
|
||||
if (SporkValueIsActive(nSporkID, nSporkValue)) {
|
||||
return nSporkValue < GetAdjustedTime();
|
||||
}
|
||||
|
||||
if (mapSporkDefaults.count(nSporkID)) {
|
||||
return mapSporkDefaults[nSporkID] < GetAdjustedTime();
|
||||
}
|
||||
|
||||
LogPrint(BCLog::SPORK, "CSporkManager::IsSporkActive -- Unknown Spork ID %d\n", nSporkID);
|
||||
return false;
|
||||
int64_t nSporkValue = GetSporkValue(nSporkID);
|
||||
return nSporkValue < GetAdjustedTime();
|
||||
}
|
||||
|
||||
int64_t CSporkManager::GetSporkValue(int nSporkID)
|
||||
int64_t CSporkManager::GetSporkValue(SporkId nSporkID)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
@ -270,50 +268,33 @@ int64_t CSporkManager::GetSporkValue(int nSporkID)
|
||||
return nSporkValue;
|
||||
}
|
||||
|
||||
if (mapSporkDefaults.count(nSporkID)) {
|
||||
return mapSporkDefaults[nSporkID];
|
||||
auto it = sporkDefsById.find(nSporkID);
|
||||
if (it != sporkDefsById.end()) {
|
||||
return it->second->defaultValue;
|
||||
}
|
||||
|
||||
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkValue -- Unknown Spork ID %d\n", nSporkID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CSporkManager::GetSporkIDByName(const std::string& strName)
|
||||
SporkId CSporkManager::GetSporkIDByName(const std::string& strName)
|
||||
{
|
||||
if (strName == "SPORK_2_INSTANTSEND_ENABLED") return SPORK_2_INSTANTSEND_ENABLED;
|
||||
if (strName == "SPORK_3_INSTANTSEND_BLOCK_FILTERING") return SPORK_3_INSTANTSEND_BLOCK_FILTERING;
|
||||
if (strName == "SPORK_5_INSTANTSEND_MAX_VALUE") return SPORK_5_INSTANTSEND_MAX_VALUE;
|
||||
if (strName == "SPORK_6_NEW_SIGS") return SPORK_6_NEW_SIGS;
|
||||
if (strName == "SPORK_9_SUPERBLOCKS_ENABLED") return SPORK_9_SUPERBLOCKS_ENABLED;
|
||||
if (strName == "SPORK_12_RECONSIDER_BLOCKS") return SPORK_12_RECONSIDER_BLOCKS;
|
||||
if (strName == "SPORK_15_DETERMINISTIC_MNS_ENABLED") return SPORK_15_DETERMINISTIC_MNS_ENABLED;
|
||||
if (strName == "SPORK_16_INSTANTSEND_AUTOLOCKS") return SPORK_16_INSTANTSEND_AUTOLOCKS;
|
||||
if (strName == "SPORK_17_QUORUM_DKG_ENABLED") return SPORK_17_QUORUM_DKG_ENABLED;
|
||||
if (strName == "SPORK_19_CHAINLOCKS_ENABLED") return SPORK_19_CHAINLOCKS_ENABLED;
|
||||
if (strName == "SPORK_20_INSTANTSEND_LLMQ_BASED") return SPORK_20_INSTANTSEND_LLMQ_BASED;
|
||||
|
||||
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkIDByName -- Unknown Spork name '%s'\n", strName);
|
||||
return -1;
|
||||
auto it = sporkDefsByName.find(strName);
|
||||
if (it == sporkDefsByName.end()) {
|
||||
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkIDByName -- Unknown Spork name '%s'\n", strName);
|
||||
return SPORK_INVALID;
|
||||
}
|
||||
return it->second->sporkId;
|
||||
}
|
||||
|
||||
std::string CSporkManager::GetSporkNameByID(int nSporkID)
|
||||
std::string CSporkManager::GetSporkNameByID(SporkId nSporkID)
|
||||
{
|
||||
switch (nSporkID) {
|
||||
case SPORK_2_INSTANTSEND_ENABLED: return "SPORK_2_INSTANTSEND_ENABLED";
|
||||
case SPORK_3_INSTANTSEND_BLOCK_FILTERING: return "SPORK_3_INSTANTSEND_BLOCK_FILTERING";
|
||||
case SPORK_5_INSTANTSEND_MAX_VALUE: return "SPORK_5_INSTANTSEND_MAX_VALUE";
|
||||
case SPORK_6_NEW_SIGS: return "SPORK_6_NEW_SIGS";
|
||||
case SPORK_9_SUPERBLOCKS_ENABLED: return "SPORK_9_SUPERBLOCKS_ENABLED";
|
||||
case SPORK_12_RECONSIDER_BLOCKS: return "SPORK_12_RECONSIDER_BLOCKS";
|
||||
case SPORK_15_DETERMINISTIC_MNS_ENABLED: return "SPORK_15_DETERMINISTIC_MNS_ENABLED";
|
||||
case SPORK_16_INSTANTSEND_AUTOLOCKS: return "SPORK_16_INSTANTSEND_AUTOLOCKS";
|
||||
case SPORK_17_QUORUM_DKG_ENABLED: return "SPORK_17_QUORUM_DKG_ENABLED";
|
||||
case SPORK_19_CHAINLOCKS_ENABLED: return "SPORK_19_CHAINLOCKS_ENABLED";
|
||||
case SPORK_20_INSTANTSEND_LLMQ_BASED: return "SPORK_20_INSTANTSEND_LLMQ_BASED";
|
||||
default:
|
||||
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkNameByID -- Unknown Spork ID %d\n", nSporkID);
|
||||
return "Unknown";
|
||||
auto it = sporkDefsById.find(nSporkID);
|
||||
if (it == sporkDefsById.end()) {
|
||||
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkNameByID -- Unknown Spork ID %d\n", nSporkID);
|
||||
return "Unknown";
|
||||
}
|
||||
return it->second->name;
|
||||
}
|
||||
|
||||
bool CSporkManager::GetSporkByHash(const uint256& hash, CSporkMessage &sporkRet)
|
||||
|
64
src/spork.h
64
src/spork.h
@ -20,22 +20,31 @@ class CSporkManager;
|
||||
Don't ever reuse these IDs for other sporks
|
||||
- This would result in old clients getting confused about which spork is for what
|
||||
*/
|
||||
static const int SPORK_2_INSTANTSEND_ENABLED = 10001;
|
||||
static const int SPORK_3_INSTANTSEND_BLOCK_FILTERING = 10002;
|
||||
static const int SPORK_5_INSTANTSEND_MAX_VALUE = 10004;
|
||||
static const int SPORK_6_NEW_SIGS = 10005;
|
||||
static const int SPORK_9_SUPERBLOCKS_ENABLED = 10008;
|
||||
static const int SPORK_12_RECONSIDER_BLOCKS = 10011;
|
||||
static const int SPORK_15_DETERMINISTIC_MNS_ENABLED = 10014;
|
||||
static const int SPORK_16_INSTANTSEND_AUTOLOCKS = 10015;
|
||||
static const int SPORK_17_QUORUM_DKG_ENABLED = 10016;
|
||||
static const int SPORK_19_CHAINLOCKS_ENABLED = 10018;
|
||||
static const int SPORK_20_INSTANTSEND_LLMQ_BASED = 10019;
|
||||
enum SporkId : int32_t {
|
||||
SPORK_2_INSTANTSEND_ENABLED = 10001,
|
||||
SPORK_3_INSTANTSEND_BLOCK_FILTERING = 10002,
|
||||
SPORK_5_INSTANTSEND_MAX_VALUE = 10004,
|
||||
SPORK_6_NEW_SIGS = 10005,
|
||||
SPORK_9_SUPERBLOCKS_ENABLED = 10008,
|
||||
SPORK_12_RECONSIDER_BLOCKS = 10011,
|
||||
SPORK_15_DETERMINISTIC_MNS_ENABLED = 10014,
|
||||
SPORK_16_INSTANTSEND_AUTOLOCKS = 10015,
|
||||
SPORK_17_QUORUM_DKG_ENABLED = 10016,
|
||||
SPORK_19_CHAINLOCKS_ENABLED = 10018,
|
||||
SPORK_20_INSTANTSEND_LLMQ_BASED = 10019,
|
||||
|
||||
static const int SPORK_START = SPORK_2_INSTANTSEND_ENABLED;
|
||||
static const int SPORK_END = SPORK_20_INSTANTSEND_LLMQ_BASED;
|
||||
SPORK_INVALID = -1,
|
||||
};
|
||||
template<> struct is_serializable_enum<SporkId> : std::true_type {};
|
||||
|
||||
extern std::map<int, int64_t> mapSporkDefaults;
|
||||
struct CSporkDef
|
||||
{
|
||||
SporkId sporkId{SPORK_INVALID};
|
||||
int64_t defaultValue{0};
|
||||
std::string name;
|
||||
};
|
||||
|
||||
extern std::vector<CSporkDef> sporkDefs;
|
||||
extern CSporkManager sporkManager;
|
||||
|
||||
/**
|
||||
@ -62,18 +71,18 @@ private:
|
||||
std::vector<unsigned char> vchSig;
|
||||
|
||||
public:
|
||||
int nSporkID;
|
||||
SporkId nSporkID;
|
||||
int64_t nValue;
|
||||
int64_t nTimeSigned;
|
||||
|
||||
CSporkMessage(int nSporkID, int64_t nValue, int64_t nTimeSigned) :
|
||||
CSporkMessage(SporkId nSporkID, int64_t nValue, int64_t nTimeSigned) :
|
||||
nSporkID(nSporkID),
|
||||
nValue(nValue),
|
||||
nTimeSigned(nTimeSigned)
|
||||
{}
|
||||
|
||||
CSporkMessage() :
|
||||
nSporkID(0),
|
||||
nSporkID((SporkId)0),
|
||||
nValue(0),
|
||||
nTimeSigned(0)
|
||||
{}
|
||||
@ -137,9 +146,12 @@ class CSporkManager
|
||||
private:
|
||||
static const std::string SERIALIZATION_VERSION_STRING;
|
||||
|
||||
std::unordered_map<SporkId, CSporkDef*> sporkDefsById;
|
||||
std::unordered_map<std::string, CSporkDef*> sporkDefsByName;
|
||||
|
||||
mutable CCriticalSection cs;
|
||||
std::unordered_map<uint256, CSporkMessage> mapSporksByHash;
|
||||
std::unordered_map<int, std::map<CKeyID, CSporkMessage> > mapSporksActive;
|
||||
std::unordered_map<SporkId, std::map<CKeyID, CSporkMessage> > mapSporksActive;
|
||||
|
||||
std::set<CKeyID> setSporkPubKeyIDs;
|
||||
int nMinSporkKeys;
|
||||
@ -149,11 +161,11 @@ private:
|
||||
* SporkValueIsActive is used to get the value agreed upon by the majority
|
||||
* of signed spork messages for a given Spork ID.
|
||||
*/
|
||||
bool SporkValueIsActive(int nSporkID, int64_t& nActiveValueRet) const;
|
||||
bool SporkValueIsActive(SporkId nSporkID, int64_t& nActiveValueRet) const;
|
||||
|
||||
public:
|
||||
|
||||
CSporkManager() {}
|
||||
CSporkManager();
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
@ -209,13 +221,13 @@ public:
|
||||
*
|
||||
* Currently only used with Spork 12.
|
||||
*/
|
||||
void ExecuteSpork(int nSporkID, int nValue);
|
||||
void ExecuteSpork(SporkId nSporkID, int nValue);
|
||||
|
||||
/**
|
||||
* UpdateSpork is used by the spork RPC command to set a new spork value, sign
|
||||
* and broadcast the spork message.
|
||||
*/
|
||||
bool UpdateSpork(int nSporkID, int64_t nValue, CConnman& connman);
|
||||
bool UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& connman);
|
||||
|
||||
/**
|
||||
* IsSporkActive returns a bool for time-based sporks, and should be used
|
||||
@ -226,23 +238,23 @@ public:
|
||||
* instead, and therefore this method doesn't make sense and should not be
|
||||
* used.
|
||||
*/
|
||||
bool IsSporkActive(int nSporkID);
|
||||
bool IsSporkActive(SporkId nSporkID);
|
||||
|
||||
/**
|
||||
* GetSporkValue returns the spork value given a Spork ID. If no active spork
|
||||
* message has yet been received by the node, it returns the default value.
|
||||
*/
|
||||
int64_t GetSporkValue(int nSporkID);
|
||||
int64_t GetSporkValue(SporkId nSporkID);
|
||||
|
||||
/**
|
||||
* GetSporkIDByName returns the internal Spork ID given the spork name.
|
||||
*/
|
||||
int GetSporkIDByName(const std::string& strName);
|
||||
SporkId GetSporkIDByName(const std::string& strName);
|
||||
|
||||
/**
|
||||
* GetSporkNameByID returns the spork name as a string, given a Spork ID.
|
||||
*/
|
||||
std::string GetSporkNameByID(int nSporkID);
|
||||
std::string GetSporkNameByID(SporkId nSporkID);
|
||||
|
||||
/**
|
||||
* GetSporkByHash returns a spork message given a hash of the spork message.
|
||||
|
Loading…
Reference in New Issue
Block a user