0diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
1index abd99fc365..731c0a070f 100644
2--- a/src/script/interpreter.cpp
3+++ b/src/script/interpreter.cpp
4@@ -2163,36 +2163,6 @@ size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey,
5 return 0;
6 }
7
8-const std::map<std::string, script_verify_flag_name>& ScriptFlagNamesToEnum()
9-{
10-#define FLAG_NAME(flag) {std::string(#flag), SCRIPT_VERIFY_##flag}
11- static const std::map<std::string, script_verify_flag_name> g_names_to_enum{
12- FLAG_NAME(P2SH),
13- FLAG_NAME(STRICTENC),
14- FLAG_NAME(DERSIG),
15- FLAG_NAME(LOW_S),
16- FLAG_NAME(SIGPUSHONLY),
17- FLAG_NAME(MINIMALDATA),
18- FLAG_NAME(NULLDUMMY),
19- FLAG_NAME(DISCOURAGE_UPGRADABLE_NOPS),
20- FLAG_NAME(CLEANSTACK),
21- FLAG_NAME(MINIMALIF),
22- FLAG_NAME(NULLFAIL),
23- FLAG_NAME(CHECKLOCKTIMEVERIFY),
24- FLAG_NAME(CHECKSEQUENCEVERIFY),
25- FLAG_NAME(WITNESS),
26- FLAG_NAME(DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM),
27- FLAG_NAME(WITNESS_PUBKEYTYPE),
28- FLAG_NAME(CONST_SCRIPTCODE),
29- FLAG_NAME(TAPROOT),
30- FLAG_NAME(DISCOURAGE_UPGRADABLE_PUBKEYTYPE),
31- FLAG_NAME(DISCOURAGE_OP_SUCCESS),
32- FLAG_NAME(DISCOURAGE_UPGRADABLE_TAPROOT_VERSION),
33- };
34-#undef FLAG_NAME
35- return g_names_to_enum;
36-}
37-
38 std::vector<std::string> GetScriptFlagNames(script_verify_flags flags)
39 {
40 std::vector<std::string> res;
41@@ -2200,9 +2170,9 @@ std::vector<std::string> GetScriptFlagNames(script_verify_flags flags)
42 return res;
43 }
44 script_verify_flags leftover = flags;
45- for (const auto& [name, flag] : ScriptFlagNamesToEnum()) {
46+ for (const auto& [name, flag] : SCRIPT_FLAG_NAMES) {
47 if ((flags & flag) != 0) {
48- res.push_back(name);
49+ res.emplace_back(name);
50 leftover &= ~flag;
51 }
52 }
53diff --git a/src/script/interpreter.h b/src/script/interpreter.h
54index 7f8a1f7a41..04611bc5d6 100644
55--- a/src/script/interpreter.h
56+++ b/src/script/interpreter.h
57@@ -381,7 +381,29 @@ size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey,
58
59 int FindAndDelete(CScript& script, const CScript& b);
60
61-const std::map<std::string, script_verify_flag_name>& ScriptFlagNamesToEnum();
62+inline constexpr std::array SCRIPT_FLAG_NAMES{std::to_array<std::pair<std::string_view, script_verify_flag_name>>({
63+ {"CHECKLOCKTIMEVERIFY", SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY},
64+ {"CHECKSEQUENCEVERIFY", SCRIPT_VERIFY_CHECKSEQUENCEVERIFY},
65+ {"CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK},
66+ {"CONST_SCRIPTCODE", SCRIPT_VERIFY_CONST_SCRIPTCODE},
67+ {"DERSIG", SCRIPT_VERIFY_DERSIG},
68+ {"DISCOURAGE_OP_SUCCESS", SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS},
69+ {"DISCOURAGE_UPGRADABLE_NOPS", SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS},
70+ {"DISCOURAGE_UPGRADABLE_PUBKEYTYPE", SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE},
71+ {"DISCOURAGE_UPGRADABLE_TAPROOT_VERSION", SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION},
72+ {"DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM", SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM},
73+ {"LOW_S", SCRIPT_VERIFY_LOW_S},
74+ {"MINIMALDATA", SCRIPT_VERIFY_MINIMALDATA},
75+ {"MINIMALIF", SCRIPT_VERIFY_MINIMALIF},
76+ {"NULLDUMMY", SCRIPT_VERIFY_NULLDUMMY},
77+ {"NULLFAIL", SCRIPT_VERIFY_NULLFAIL},
78+ {"P2SH", SCRIPT_VERIFY_P2SH},
79+ {"SIGPUSHONLY", SCRIPT_VERIFY_SIGPUSHONLY},
80+ {"STRICTENC", SCRIPT_VERIFY_STRICTENC},
81+ {"TAPROOT", SCRIPT_VERIFY_TAPROOT},
82+ {"WITNESS", SCRIPT_VERIFY_WITNESS},
83+ {"WITNESS_PUBKEYTYPE", SCRIPT_VERIFY_WITNESS_PUBKEYTYPE},
84+})};
85
86 std::vector<std::string> GetScriptFlagNames(script_verify_flags flags);
87
88diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
89index 0ab9fbb479..e234153825 100644
90--- a/src/test/transaction_tests.cpp
91+++ b/src/test/transaction_tests.cpp
92@@ -50,7 +50,6 @@ typedef std::vector<unsigned char> valtype;
93 static CFeeRate g_dust{DUST_RELAY_TX_FEE};
94 static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG};
95
96-static const std::map<std::string, script_verify_flag_name>& mapFlagNames = ScriptFlagNamesToEnum();
97
98 script_verify_flags ParseScriptFlags(std::string strFlags)
99 {
100@@ -60,20 +59,21 @@ script_verify_flags ParseScriptFlags(std::string strFlags)
101 std::vector<std::string> words = SplitString(strFlags, ',');
102 for (const std::string& word : words)
103 {
104- if (!mapFlagNames.count(word)) {
105+ auto it = std::ranges::find(SCRIPT_FLAG_NAMES, word, &decltype(SCRIPT_FLAG_NAMES)::value_type::first);
106+ if (it == SCRIPT_FLAG_NAMES.end()) {
107 BOOST_ERROR("Bad test: unknown verification flag '" << word << "'");
108 continue;
109 }
110- flags |= mapFlagNames.at(word);
111+ flags |= it->second;
112 }
113 return flags;
114 }
115
116-// Check that all flags in STANDARD_SCRIPT_VERIFY_FLAGS are present in mapFlagNames.
117-bool CheckMapFlagNames()
118+// Check that all flags in STANDARD_SCRIPT_VERIFY_FLAGS are present in SCRIPT_FLAG_NAMES.
119+bool CheckScriptFlagNames()
120 {
121 script_verify_flags standard_flags_missing{STANDARD_SCRIPT_VERIFY_FLAGS};
122- for (const auto& pair : mapFlagNames) {
123+ for (const auto& pair : SCRIPT_FLAG_NAMES) {
124 standard_flags_missing &= ~(pair.second);
125 }
126 return standard_flags_missing == 0;
127@@ -142,11 +142,11 @@ script_verify_flags FillFlags(script_verify_flags flags)
128 // Exclude each possible script verify flag from flags. Returns a set of these flag combinations
129 // that are valid and without duplicates. For example: if flags=1111 and the 4 possible flags are
130 // 0001, 0010, 0100, and 1000, this should return the set {0111, 1011, 1101, 1110}.
131-// Assumes that mapFlagNames contains all script verify flags.
132+// Assumes that SCRIPT_FLAG_NAMES contains all script verify flags.
133 std::set<script_verify_flags> ExcludeIndividualFlags(script_verify_flags flags)
134 {
135 std::set<script_verify_flags> flags_combos;
136- for (const auto& pair : mapFlagNames) {
137+ for (const auto& pair : SCRIPT_FLAG_NAMES) {
138 script_verify_flags flags_excluding_one = TrimFlags(flags & ~(pair.second));
139 if (flags != flags_excluding_one) {
140 flags_combos.insert(flags_excluding_one);
141@@ -159,7 +159,7 @@ BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
142
143 BOOST_AUTO_TEST_CASE(tx_valid)
144 {
145- BOOST_CHECK_MESSAGE(CheckMapFlagNames(), "mapFlagNames is missing a script verification flag");
146+ BOOST_CHECK_MESSAGE(CheckScriptFlagNames(), "SCRIPT_FLAG_NAMES is missing a script verification flag");
147 // Read tests from test/data/tx_valid.json
148 UniValue tests = read_json(json_tests::tx_valid);
149
150@@ -223,7 +223,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
151 "Tx unexpectedly failed: " << strTest);
152
153 // Backwards compatibility of script verification flags: Removing any flag(s) should not invalidate a valid transaction
154- for (const auto& [name, flag] : mapFlagNames) {
155+ for (const auto& [name, flag] : SCRIPT_FLAG_NAMES) {
156 // Removing individual flags
157 script_verify_flags flags = TrimFlags(~(verify_flags | flag));
158 if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /*expect_valid=*/true)) {
159@@ -314,7 +314,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
160 "Tx unexpectedly passed: " << strTest);
161
162 // Backwards compatibility of script verification flags: Adding any flag(s) should not validate an invalid transaction
163- for (const auto& [name, flag] : mapFlagNames) {
164+ for (const auto& [name, flag] : SCRIPT_FLAG_NAMES) {
165 script_verify_flags flags = FillFlags(verify_flags | flag);
166 // Adding individual flags
167 if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /*expect_valid=*/false)) {