Skip to content

Commit fc73b4d

Browse files
codablockUdjinM6
authored andcommitted
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.
1 parent a149ca7 commit fc73b4d

File tree

3 files changed

+92
-101
lines changed

3 files changed

+92
-101
lines changed

src/rpc/misc.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,16 +253,14 @@ UniValue spork(const JSONRPCRequest& request)
253253
std:: string strCommand = request.params[0].get_str();
254254
if (strCommand == "show") {
255255
UniValue ret(UniValue::VOBJ);
256-
for(int nSporkID = SPORK_START; nSporkID <= SPORK_END; nSporkID++){
257-
if(sporkManager.GetSporkNameByID(nSporkID) != "Unknown")
258-
ret.push_back(Pair(sporkManager.GetSporkNameByID(nSporkID), sporkManager.GetSporkValue(nSporkID)));
256+
for (const auto& sporkDef : sporkDefs) {
257+
ret.push_back(Pair(sporkDef.name, sporkManager.GetSporkValue(sporkDef.sporkId)));
259258
}
260259
return ret;
261260
} else if(strCommand == "active"){
262261
UniValue ret(UniValue::VOBJ);
263-
for(int nSporkID = SPORK_START; nSporkID <= SPORK_END; nSporkID++){
264-
if(sporkManager.GetSporkNameByID(nSporkID) != "Unknown")
265-
ret.push_back(Pair(sporkManager.GetSporkNameByID(nSporkID), sporkManager.IsSporkActive(nSporkID)));
262+
for (const auto& sporkDef : sporkDefs) {
263+
ret.push_back(Pair(sporkDef.name, sporkManager.IsSporkActive(sporkDef.sporkId)));
266264
}
267265
return ret;
268266
}
@@ -291,8 +289,8 @@ UniValue spork(const JSONRPCRequest& request)
291289
+ HelpExampleRpc("spork", "\"show\""));
292290
} else {
293291
// advanced mode, update spork values
294-
int nSporkID = sporkManager.GetSporkIDByName(request.params[0].get_str());
295-
if(nSporkID == -1)
292+
SporkId nSporkID = sporkManager.GetSporkIDByName(request.params[0].get_str());
293+
if(nSporkID == SPORK_INVALID)
296294
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid spork name");
297295

298296
if (!g_connman)

src/spork.cpp

Lines changed: 46 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,34 @@
1313

1414
#include <string>
1515

16-
CSporkManager sporkManager;
17-
1816
const std::string CSporkManager::SERIALIZATION_VERSION_STRING = "CSporkManager-Version-2";
1917

20-
std::map<int, int64_t> mapSporkDefaults = {
21-
{SPORK_2_INSTANTSEND_ENABLED, 0}, // ON
22-
{SPORK_3_INSTANTSEND_BLOCK_FILTERING, 0}, // ON
23-
{SPORK_5_INSTANTSEND_MAX_VALUE, 1000}, // 1000 Dash
24-
{SPORK_6_NEW_SIGS, 4070908800ULL}, // OFF
25-
{SPORK_9_SUPERBLOCKS_ENABLED, 4070908800ULL}, // OFF
26-
{SPORK_12_RECONSIDER_BLOCKS, 0}, // 0 BLOCKS
27-
{SPORK_15_DETERMINISTIC_MNS_ENABLED, 4070908800ULL}, // OFF
28-
{SPORK_16_INSTANTSEND_AUTOLOCKS, 4070908800ULL}, // OFF
29-
{SPORK_17_QUORUM_DKG_ENABLED, 4070908800ULL}, // OFF
30-
{SPORK_19_CHAINLOCKS_ENABLED, 4070908800ULL}, // OFF
31-
{SPORK_20_INSTANTSEND_LLMQ_BASED, 4070908800ULL}, // OFF
18+
#define MAKE_SPORK_DEF(name, defaultValue) CSporkDef{name, defaultValue, #name}
19+
std::vector<CSporkDef> sporkDefs = {
20+
MAKE_SPORK_DEF(SPORK_2_INSTANTSEND_ENABLED, 0), // ON
21+
MAKE_SPORK_DEF(SPORK_3_INSTANTSEND_BLOCK_FILTERING, 0), // ON
22+
MAKE_SPORK_DEF(SPORK_5_INSTANTSEND_MAX_VALUE, 1000), // 1000 Dash
23+
MAKE_SPORK_DEF(SPORK_6_NEW_SIGS, 4070908800ULL), // OFF
24+
MAKE_SPORK_DEF(SPORK_9_SUPERBLOCKS_ENABLED, 4070908800ULL), // OFF
25+
MAKE_SPORK_DEF(SPORK_12_RECONSIDER_BLOCKS, 0), // 0 BLOCKS
26+
MAKE_SPORK_DEF(SPORK_15_DETERMINISTIC_MNS_ENABLED, 4070908800ULL), // OFF
27+
MAKE_SPORK_DEF(SPORK_16_INSTANTSEND_AUTOLOCKS, 4070908800ULL), // OFF
28+
MAKE_SPORK_DEF(SPORK_17_QUORUM_DKG_ENABLED, 4070908800ULL), // OFF
29+
MAKE_SPORK_DEF(SPORK_19_CHAINLOCKS_ENABLED, 4070908800ULL), // OFF
30+
MAKE_SPORK_DEF(SPORK_20_INSTANTSEND_LLMQ_BASED, 4070908800ULL), // OFF
3231
};
3332

34-
bool CSporkManager::SporkValueIsActive(int nSporkID, int64_t &nActiveValueRet) const
33+
CSporkManager sporkManager;
34+
35+
CSporkManager::CSporkManager()
36+
{
37+
for (auto& sporkDef : sporkDefs) {
38+
sporkDefsById.emplace(sporkDef.sporkId, &sporkDef);
39+
sporkDefsByName.emplace(sporkDef.name, &sporkDef);
40+
}
41+
}
42+
43+
bool CSporkManager::SporkValueIsActive(SporkId nSporkID, int64_t &nActiveValueRet) const
3544
{
3645
LOCK(cs);
3746

@@ -192,7 +201,7 @@ void CSporkManager::ProcessSpork(CNode* pfrom, const std::string& strCommand, CD
192201

193202
}
194203

195-
void CSporkManager::ExecuteSpork(int nSporkID, int nValue)
204+
void CSporkManager::ExecuteSpork(SporkId nSporkID, int nValue)
196205
{
197206
//correct fork via spork technology
198207
if(nSporkID == SPORK_12_RECONSIDER_BLOCKS && nValue > 0) {
@@ -221,7 +230,7 @@ void CSporkManager::ExecuteSpork(int nSporkID, int nValue)
221230
}
222231
}
223232

224-
bool CSporkManager::UpdateSpork(int nSporkID, int64_t nValue, CConnman& connman)
233+
bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& connman)
225234
{
226235
CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetAdjustedTime());
227236

@@ -244,24 +253,13 @@ bool CSporkManager::UpdateSpork(int nSporkID, int64_t nValue, CConnman& connman)
244253
return false;
245254
}
246255

247-
bool CSporkManager::IsSporkActive(int nSporkID)
256+
bool CSporkManager::IsSporkActive(SporkId nSporkID)
248257
{
249-
LOCK(cs);
250-
int64_t nSporkValue = -1;
251-
252-
if (SporkValueIsActive(nSporkID, nSporkValue)) {
253-
return nSporkValue < GetAdjustedTime();
254-
}
255-
256-
if (mapSporkDefaults.count(nSporkID)) {
257-
return mapSporkDefaults[nSporkID] < GetAdjustedTime();
258-
}
259-
260-
LogPrint(BCLog::SPORK, "CSporkManager::IsSporkActive -- Unknown Spork ID %d\n", nSporkID);
261-
return false;
258+
int64_t nSporkValue = GetSporkValue(nSporkID);
259+
return nSporkValue < GetAdjustedTime();
262260
}
263261

264-
int64_t CSporkManager::GetSporkValue(int nSporkID)
262+
int64_t CSporkManager::GetSporkValue(SporkId nSporkID)
265263
{
266264
LOCK(cs);
267265

@@ -270,50 +268,33 @@ int64_t CSporkManager::GetSporkValue(int nSporkID)
270268
return nSporkValue;
271269
}
272270

273-
if (mapSporkDefaults.count(nSporkID)) {
274-
return mapSporkDefaults[nSporkID];
271+
auto it = sporkDefsById.find(nSporkID);
272+
if (it != sporkDefsById.end()) {
273+
return it->second->defaultValue;
275274
}
276275

277276
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkValue -- Unknown Spork ID %d\n", nSporkID);
278277
return -1;
279278
}
280279

281-
int CSporkManager::GetSporkIDByName(const std::string& strName)
280+
SporkId CSporkManager::GetSporkIDByName(const std::string& strName)
282281
{
283-
if (strName == "SPORK_2_INSTANTSEND_ENABLED") return SPORK_2_INSTANTSEND_ENABLED;
284-
if (strName == "SPORK_3_INSTANTSEND_BLOCK_FILTERING") return SPORK_3_INSTANTSEND_BLOCK_FILTERING;
285-
if (strName == "SPORK_5_INSTANTSEND_MAX_VALUE") return SPORK_5_INSTANTSEND_MAX_VALUE;
286-
if (strName == "SPORK_6_NEW_SIGS") return SPORK_6_NEW_SIGS;
287-
if (strName == "SPORK_9_SUPERBLOCKS_ENABLED") return SPORK_9_SUPERBLOCKS_ENABLED;
288-
if (strName == "SPORK_12_RECONSIDER_BLOCKS") return SPORK_12_RECONSIDER_BLOCKS;
289-
if (strName == "SPORK_15_DETERMINISTIC_MNS_ENABLED") return SPORK_15_DETERMINISTIC_MNS_ENABLED;
290-
if (strName == "SPORK_16_INSTANTSEND_AUTOLOCKS") return SPORK_16_INSTANTSEND_AUTOLOCKS;
291-
if (strName == "SPORK_17_QUORUM_DKG_ENABLED") return SPORK_17_QUORUM_DKG_ENABLED;
292-
if (strName == "SPORK_19_CHAINLOCKS_ENABLED") return SPORK_19_CHAINLOCKS_ENABLED;
293-
if (strName == "SPORK_20_INSTANTSEND_LLMQ_BASED") return SPORK_20_INSTANTSEND_LLMQ_BASED;
294-
295-
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkIDByName -- Unknown Spork name '%s'\n", strName);
296-
return -1;
282+
auto it = sporkDefsByName.find(strName);
283+
if (it == sporkDefsByName.end()) {
284+
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkIDByName -- Unknown Spork name '%s'\n", strName);
285+
return SPORK_INVALID;
286+
}
287+
return it->second->sporkId;
297288
}
298289

299-
std::string CSporkManager::GetSporkNameByID(int nSporkID)
290+
std::string CSporkManager::GetSporkNameByID(SporkId nSporkID)
300291
{
301-
switch (nSporkID) {
302-
case SPORK_2_INSTANTSEND_ENABLED: return "SPORK_2_INSTANTSEND_ENABLED";
303-
case SPORK_3_INSTANTSEND_BLOCK_FILTERING: return "SPORK_3_INSTANTSEND_BLOCK_FILTERING";
304-
case SPORK_5_INSTANTSEND_MAX_VALUE: return "SPORK_5_INSTANTSEND_MAX_VALUE";
305-
case SPORK_6_NEW_SIGS: return "SPORK_6_NEW_SIGS";
306-
case SPORK_9_SUPERBLOCKS_ENABLED: return "SPORK_9_SUPERBLOCKS_ENABLED";
307-
case SPORK_12_RECONSIDER_BLOCKS: return "SPORK_12_RECONSIDER_BLOCKS";
308-
case SPORK_15_DETERMINISTIC_MNS_ENABLED: return "SPORK_15_DETERMINISTIC_MNS_ENABLED";
309-
case SPORK_16_INSTANTSEND_AUTOLOCKS: return "SPORK_16_INSTANTSEND_AUTOLOCKS";
310-
case SPORK_17_QUORUM_DKG_ENABLED: return "SPORK_17_QUORUM_DKG_ENABLED";
311-
case SPORK_19_CHAINLOCKS_ENABLED: return "SPORK_19_CHAINLOCKS_ENABLED";
312-
case SPORK_20_INSTANTSEND_LLMQ_BASED: return "SPORK_20_INSTANTSEND_LLMQ_BASED";
313-
default:
314-
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkNameByID -- Unknown Spork ID %d\n", nSporkID);
315-
return "Unknown";
292+
auto it = sporkDefsById.find(nSporkID);
293+
if (it == sporkDefsById.end()) {
294+
LogPrint(BCLog::SPORK, "CSporkManager::GetSporkNameByID -- Unknown Spork ID %d\n", nSporkID);
295+
return "Unknown";
316296
}
297+
return it->second->name;
317298
}
318299

319300
bool CSporkManager::GetSporkByHash(const uint256& hash, CSporkMessage &sporkRet)

src/spork.h

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,31 @@ class CSporkManager;
2020
Don't ever reuse these IDs for other sporks
2121
- This would result in old clients getting confused about which spork is for what
2222
*/
23-
static const int SPORK_2_INSTANTSEND_ENABLED = 10001;
24-
static const int SPORK_3_INSTANTSEND_BLOCK_FILTERING = 10002;
25-
static const int SPORK_5_INSTANTSEND_MAX_VALUE = 10004;
26-
static const int SPORK_6_NEW_SIGS = 10005;
27-
static const int SPORK_9_SUPERBLOCKS_ENABLED = 10008;
28-
static const int SPORK_12_RECONSIDER_BLOCKS = 10011;
29-
static const int SPORK_15_DETERMINISTIC_MNS_ENABLED = 10014;
30-
static const int SPORK_16_INSTANTSEND_AUTOLOCKS = 10015;
31-
static const int SPORK_17_QUORUM_DKG_ENABLED = 10016;
32-
static const int SPORK_19_CHAINLOCKS_ENABLED = 10018;
33-
static const int SPORK_20_INSTANTSEND_LLMQ_BASED = 10019;
34-
35-
static const int SPORK_START = SPORK_2_INSTANTSEND_ENABLED;
36-
static const int SPORK_END = SPORK_20_INSTANTSEND_LLMQ_BASED;
37-
38-
extern std::map<int, int64_t> mapSporkDefaults;
23+
enum SporkId : int32_t {
24+
SPORK_2_INSTANTSEND_ENABLED = 10001,
25+
SPORK_3_INSTANTSEND_BLOCK_FILTERING = 10002,
26+
SPORK_5_INSTANTSEND_MAX_VALUE = 10004,
27+
SPORK_6_NEW_SIGS = 10005,
28+
SPORK_9_SUPERBLOCKS_ENABLED = 10008,
29+
SPORK_12_RECONSIDER_BLOCKS = 10011,
30+
SPORK_15_DETERMINISTIC_MNS_ENABLED = 10014,
31+
SPORK_16_INSTANTSEND_AUTOLOCKS = 10015,
32+
SPORK_17_QUORUM_DKG_ENABLED = 10016,
33+
SPORK_19_CHAINLOCKS_ENABLED = 10018,
34+
SPORK_20_INSTANTSEND_LLMQ_BASED = 10019,
35+
36+
SPORK_INVALID = -1,
37+
};
38+
template<> struct is_serializable_enum<SporkId> : std::true_type {};
39+
40+
struct CSporkDef
41+
{
42+
SporkId sporkId{SPORK_INVALID};
43+
int64_t defaultValue{0};
44+
std::string name;
45+
};
46+
47+
extern std::vector<CSporkDef> sporkDefs;
3948
extern CSporkManager sporkManager;
4049

4150
/**
@@ -62,18 +71,18 @@ class CSporkMessage
6271
std::vector<unsigned char> vchSig;
6372

6473
public:
65-
int nSporkID;
74+
SporkId nSporkID;
6675
int64_t nValue;
6776
int64_t nTimeSigned;
6877

69-
CSporkMessage(int nSporkID, int64_t nValue, int64_t nTimeSigned) :
78+
CSporkMessage(SporkId nSporkID, int64_t nValue, int64_t nTimeSigned) :
7079
nSporkID(nSporkID),
7180
nValue(nValue),
7281
nTimeSigned(nTimeSigned)
7382
{}
7483

7584
CSporkMessage() :
76-
nSporkID(0),
85+
nSporkID((SporkId)0),
7786
nValue(0),
7887
nTimeSigned(0)
7988
{}
@@ -137,9 +146,12 @@ class CSporkManager
137146
private:
138147
static const std::string SERIALIZATION_VERSION_STRING;
139148

149+
std::unordered_map<SporkId, CSporkDef*> sporkDefsById;
150+
std::unordered_map<std::string, CSporkDef*> sporkDefsByName;
151+
140152
mutable CCriticalSection cs;
141153
std::unordered_map<uint256, CSporkMessage> mapSporksByHash;
142-
std::unordered_map<int, std::map<CKeyID, CSporkMessage> > mapSporksActive;
154+
std::unordered_map<SporkId, std::map<CKeyID, CSporkMessage> > mapSporksActive;
143155

144156
std::set<CKeyID> setSporkPubKeyIDs;
145157
int nMinSporkKeys;
@@ -149,11 +161,11 @@ class CSporkManager
149161
* SporkValueIsActive is used to get the value agreed upon by the majority
150162
* of signed spork messages for a given Spork ID.
151163
*/
152-
bool SporkValueIsActive(int nSporkID, int64_t& nActiveValueRet) const;
164+
bool SporkValueIsActive(SporkId nSporkID, int64_t& nActiveValueRet) const;
153165

154166
public:
155167

156-
CSporkManager() {}
168+
CSporkManager();
157169

158170
ADD_SERIALIZE_METHODS;
159171

@@ -209,13 +221,13 @@ class CSporkManager
209221
*
210222
* Currently only used with Spork 12.
211223
*/
212-
void ExecuteSpork(int nSporkID, int nValue);
224+
void ExecuteSpork(SporkId nSporkID, int nValue);
213225

214226
/**
215227
* UpdateSpork is used by the spork RPC command to set a new spork value, sign
216228
* and broadcast the spork message.
217229
*/
218-
bool UpdateSpork(int nSporkID, int64_t nValue, CConnman& connman);
230+
bool UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& connman);
219231

220232
/**
221233
* IsSporkActive returns a bool for time-based sporks, and should be used
@@ -226,23 +238,23 @@ class CSporkManager
226238
* instead, and therefore this method doesn't make sense and should not be
227239
* used.
228240
*/
229-
bool IsSporkActive(int nSporkID);
241+
bool IsSporkActive(SporkId nSporkID);
230242

231243
/**
232244
* GetSporkValue returns the spork value given a Spork ID. If no active spork
233245
* message has yet been received by the node, it returns the default value.
234246
*/
235-
int64_t GetSporkValue(int nSporkID);
247+
int64_t GetSporkValue(SporkId nSporkID);
236248

237249
/**
238250
* GetSporkIDByName returns the internal Spork ID given the spork name.
239251
*/
240-
int GetSporkIDByName(const std::string& strName);
252+
SporkId GetSporkIDByName(const std::string& strName);
241253

242254
/**
243255
* GetSporkNameByID returns the spork name as a string, given a Spork ID.
244256
*/
245-
std::string GetSporkNameByID(int nSporkID);
257+
std::string GetSporkNameByID(SporkId nSporkID);
246258

247259
/**
248260
* GetSporkByHash returns a spork message given a hash of the spork message.

0 commit comments

Comments
 (0)