refactor: Construct g_verify_flag_names on first use
What changed, and why it matters
This commit is a code cleanup (refactor) that changes how a lookup table of script verification flag names is created and accessed. It moves the table from a global variable constructed at program startup to a function that creates the table the first time it is called. There is no change to transaction validation rules, no bug fix, and no security-relevant behavior change.
No security action needed. Treat as ordinary code maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch replaces the global constant g_verify_flag_names with a function ScriptFlagNamesToEnum() that returns a reference to a function-local static const std::map. The map contents and consumers (GetScriptFlagNames, test helper mapFlagNames) remain identical. This is a standard ‘construct on first use’ refactor to avoid static initialization order issues. No script flags are added, removed, or redefined, and no consensus or policy logic is modified.
Changed components
src/script/interpreter.cppsrc/script/interpreter.hsrc/test/transaction_tests.cppInspect captured patch +30 / −26
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 11d31392..abd99fc3 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -2163,31 +2163,35 @@ size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey,
return 0;
}
+const std::map<std::string, script_verify_flag_name>& ScriptFlagNamesToEnum()
+{
#define FLAG_NAME(flag) {std::string(#flag), SCRIPT_VERIFY_##flag}
-const std::map<std::string, script_verify_flag_name> g_verify_flag_names{
- FLAG_NAME(P2SH),
- FLAG_NAME(STRICTENC),
- FLAG_NAME(DERSIG),
- FLAG_NAME(LOW_S),
- FLAG_NAME(SIGPUSHONLY),
- FLAG_NAME(MINIMALDATA),
- FLAG_NAME(NULLDUMMY),
- FLAG_NAME(DISCOURAGE_UPGRADABLE_NOPS),
- FLAG_NAME(CLEANSTACK),
- FLAG_NAME(MINIMALIF),
- FLAG_NAME(NULLFAIL),
- FLAG_NAME(CHECKLOCKTIMEVERIFY),
- FLAG_NAME(CHECKSEQUENCEVERIFY),
- FLAG_NAME(WITNESS),
- FLAG_NAME(DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM),
- FLAG_NAME(WITNESS_PUBKEYTYPE),
- FLAG_NAME(CONST_SCRIPTCODE),
- FLAG_NAME(TAPROOT),
- FLAG_NAME(DISCOURAGE_UPGRADABLE_PUBKEYTYPE),
- FLAG_NAME(DISCOURAGE_OP_SUCCESS),
- FLAG_NAME(DISCOURAGE_UPGRADABLE_TAPROOT_VERSION),
-};
+ static const std::map<std::string, script_verify_flag_name> g_names_to_enum{
+ FLAG_NAME(P2SH),
+ FLAG_NAME(STRICTENC),
+ FLAG_NAME(DERSIG),
+ FLAG_NAME(LOW_S),
+ FLAG_NAME(SIGPUSHONLY),
+ FLAG_NAME(MINIMALDATA),
+ FLAG_NAME(NULLDUMMY),
+ FLAG_NAME(DISCOURAGE_UPGRADABLE_NOPS),
+ FLAG_NAME(CLEANSTACK),
+ FLAG_NAME(MINIMALIF),
+ FLAG_NAME(NULLFAIL),
+ FLAG_NAME(CHECKLOCKTIMEVERIFY),
+ FLAG_NAME(CHECKSEQUENCEVERIFY),
+ FLAG_NAME(WITNESS),
+ FLAG_NAME(DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM),
+ FLAG_NAME(WITNESS_PUBKEYTYPE),
+ FLAG_NAME(CONST_SCRIPTCODE),
+ FLAG_NAME(TAPROOT),
+ FLAG_NAME(DISCOURAGE_UPGRADABLE_PUBKEYTYPE),
+ FLAG_NAME(DISCOURAGE_OP_SUCCESS),
+ FLAG_NAME(DISCOURAGE_UPGRADABLE_TAPROOT_VERSION),
+ };
#undef FLAG_NAME
+ return g_names_to_enum;
+}
std::vector<std::string> GetScriptFlagNames(script_verify_flags flags)
{
@@ -2196,7 +2200,7 @@ std::vector<std::string> GetScriptFlagNames(script_verify_flags flags)
return res;
}
script_verify_flags leftover = flags;
- for (const auto& [name, flag] : g_verify_flag_names) {
+ for (const auto& [name, flag] : ScriptFlagNamesToEnum()) {
if ((flags & flag) != 0) {
res.push_back(name);
leftover &= ~flag;
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index 986b6b0d..7f8a1f7a 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -381,7 +381,7 @@ size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey,
int FindAndDelete(CScript& script, const CScript& b);
-extern const std::map<std::string, script_verify_flag_name> g_verify_flag_names;
+const std::map<std::string, script_verify_flag_name>& ScriptFlagNamesToEnum();
std::vector<std::string> GetScriptFlagNames(script_verify_flags flags);
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index b2a70057..0ab9fbb4 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -50,7 +50,7 @@ typedef std::vector<unsigned char> valtype;
static CFeeRate g_dust{DUST_RELAY_TX_FEE};
static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG};
-static const std::map<std::string, script_verify_flag_name>& mapFlagNames = g_verify_flag_names;
+static const std::map<std::string, script_verify_flag_name>& mapFlagNames = ScriptFlagNamesToEnum();
script_verify_flags ParseScriptFlags(std::string strFlags)
{
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.