Skip to content

Commit a92e8b1

Browse files
committed
Merge bitcoin/bitcoin#32564: miniscript, refactor: Make operator""_mst consteval (re-take)
a34fb9a miniscript: Make `operator""_mst` `consteval` (Pieter Wuille) 1405216 Revert "miniscript: make operator_mst consteval" (Hennadii Stepanov) Pull request description: Same as bitcoin/bitcoin#28657, but without the refactoring required to work around [fixed](bitcoin/bitcoin#28657 (comment)) MSVC bugs. The second commit has been taken from bitcoin/bitcoin#29167. ACKs for top commit: sipa: ACK a34fb9a hodlinator: re-ACK a34fb9a Tree-SHA512: 8b531f9d6c450a8a5218865da05ffb5093d09ce2c0bee9874c0160795c4b1713928730d894ea3cd0b12b133346971ae3a00ed2fe8d9fd8a50b67a74ef81fde98
2 parents bf75c99 + a34fb9a commit a92e8b1

File tree

3 files changed

+30
-37
lines changed

3 files changed

+30
-37
lines changed

src/script/miniscript.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,7 @@ Type ComputeType(Fragment fragment, Type x, Type y, Type z, const std::vector<Ty
234234
Type acc_tl = "k"_mst;
235235
for (size_t i = 0; i < sub_types.size(); ++i) {
236236
Type t = sub_types[i];
237-
static constexpr auto WDU{"Wdu"_mst}, BDU{"Bdu"_mst};
238-
if (!(t << (i ? WDU : BDU))) return ""_mst; // Require Bdu, Wdu, Wdu, ...
237+
if (!(t << (i ? "Wdu"_mst : "Bdu"_mst))) return ""_mst; // Require Bdu, Wdu, Wdu, ...
239238
if (!(t << "e"_mst)) all_e = false;
240239
if (!(t << "m"_mst)) all_m = false;
241240
if (t << "s"_mst) num_s += 1;

src/script/miniscript.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,12 @@ class Type {
127127
//! Internal bitmap of properties (see ""_mst operator for details).
128128
uint32_t m_flags;
129129

130-
//! Internal constructor.
131-
explicit constexpr Type(uint32_t flags) noexcept : m_flags(flags) {}
130+
//! Internal constructor used by the ""_mst operator.
131+
explicit constexpr Type(uint32_t flags) : m_flags(flags) {}
132132

133133
public:
134-
//! Construction function used by the ""_mst operator.
135-
static consteval Type Make(uint32_t flags) noexcept { return Type(flags); }
134+
//! The only way to publicly construct a Type is using this literal operator.
135+
friend consteval Type operator""_mst(const char* c, size_t l);
136136

137137
//! Compute the type with the union of properties.
138138
constexpr Type operator|(Type x) const { return Type(m_flags | x.m_flags); }
@@ -156,10 +156,10 @@ class Type {
156156
//! Literal operator to construct Type objects.
157157
inline consteval Type operator""_mst(const char* c, size_t l)
158158
{
159-
Type typ{Type::Make(0)};
159+
Type typ{0};
160160

161161
for (const char *p = c; p < c + l; p++) {
162-
typ = typ | Type::Make(
162+
typ = typ | Type(
163163
*p == 'B' ? 1 << 0 : // Base type
164164
*p == 'V' ? 1 << 1 : // Verify type
165165
*p == 'K' ? 1 << 2 : // Key type
@@ -572,8 +572,7 @@ struct Node {
572572
for (const auto& sub : subs) {
573573
subsize += sub->ScriptSize();
574574
}
575-
static constexpr auto NONE_MST{""_mst};
576-
Type sub0type = subs.size() > 0 ? subs[0]->GetType() : NONE_MST;
575+
Type sub0type = subs.size() > 0 ? subs[0]->GetType() : ""_mst;
577576
return internal::ComputeScriptLen(fragment, sub0type, subsize, k, subs.size(), keys.size(), m_script_ctx);
578577
}
579578

@@ -738,10 +737,9 @@ struct Node {
738737
for (const auto& sub : subs) sub_types.push_back(sub->GetType());
739738
}
740739
// All other nodes than THRESH can be computed just from the types of the 0-3 subexpressions.
741-
static constexpr auto NONE_MST{""_mst};
742-
Type x = subs.size() > 0 ? subs[0]->GetType() : NONE_MST;
743-
Type y = subs.size() > 1 ? subs[1]->GetType() : NONE_MST;
744-
Type z = subs.size() > 2 ? subs[2]->GetType() : NONE_MST;
740+
Type x = subs.size() > 0 ? subs[0]->GetType() : ""_mst;
741+
Type y = subs.size() > 1 ? subs[1]->GetType() : ""_mst;
742+
Type z = subs.size() > 2 ? subs[2]->GetType() : ""_mst;
745743

746744
return SanitizeType(ComputeType(fragment, x, y, z, sub_types, k, data.size(), subs.size(), keys.size(), m_script_ctx));
747745
}

src/test/fuzz/miniscript.cpp

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,6 @@ std::optional<NodeInfo> ConsumeNodeStable(MsCtx script_ctx, FuzzedDataProvider&
390390
bool allow_K = (type_needed == ""_mst) || (type_needed << "K"_mst);
391391
bool allow_V = (type_needed == ""_mst) || (type_needed << "V"_mst);
392392
bool allow_W = (type_needed == ""_mst) || (type_needed << "W"_mst);
393-
static constexpr auto B{"B"_mst}, K{"K"_mst}, V{"V"_mst}, W{"W"_mst};
394393

395394
switch (provider.ConsumeIntegral<uint8_t>()) {
396395
case 0:
@@ -440,22 +439,22 @@ std::optional<NodeInfo> ConsumeNodeStable(MsCtx script_ctx, FuzzedDataProvider&
440439
}
441440
case 11:
442441
if (!(allow_B || allow_K || allow_V)) return {};
443-
return {{{B, type_needed, type_needed}, Fragment::ANDOR}};
442+
return {{{"B"_mst, type_needed, type_needed}, Fragment::ANDOR}};
444443
case 12:
445444
if (!(allow_B || allow_K || allow_V)) return {};
446-
return {{{V, type_needed}, Fragment::AND_V}};
445+
return {{{"V"_mst, type_needed}, Fragment::AND_V}};
447446
case 13:
448447
if (!allow_B) return {};
449-
return {{{B, W}, Fragment::AND_B}};
448+
return {{{"B"_mst, "W"_mst}, Fragment::AND_B}};
450449
case 15:
451450
if (!allow_B) return {};
452-
return {{{B, W}, Fragment::OR_B}};
451+
return {{{"B"_mst, "W"_mst}, Fragment::OR_B}};
453452
case 16:
454453
if (!allow_V) return {};
455-
return {{{B, V}, Fragment::OR_C}};
454+
return {{{"B"_mst, "V"_mst}, Fragment::OR_C}};
456455
case 17:
457456
if (!allow_B) return {};
458-
return {{{B, B}, Fragment::OR_D}};
457+
return {{{"B"_mst, "B"_mst}, Fragment::OR_D}};
459458
case 18:
460459
if (!(allow_B || allow_K || allow_V)) return {};
461460
return {{{type_needed, type_needed}, Fragment::OR_I}};
@@ -472,25 +471,25 @@ std::optional<NodeInfo> ConsumeNodeStable(MsCtx script_ctx, FuzzedDataProvider&
472471
}
473472
case 20:
474473
if (!allow_W) return {};
475-
return {{{B}, Fragment::WRAP_A}};
474+
return {{{"B"_mst}, Fragment::WRAP_A}};
476475
case 21:
477476
if (!allow_W) return {};
478-
return {{{B}, Fragment::WRAP_S}};
477+
return {{{"B"_mst}, Fragment::WRAP_S}};
479478
case 22:
480479
if (!allow_B) return {};
481-
return {{{K}, Fragment::WRAP_C}};
480+
return {{{"K"_mst}, Fragment::WRAP_C}};
482481
case 23:
483482
if (!allow_B) return {};
484-
return {{{V}, Fragment::WRAP_D}};
483+
return {{{"V"_mst}, Fragment::WRAP_D}};
485484
case 24:
486485
if (!allow_V) return {};
487-
return {{{B}, Fragment::WRAP_V}};
486+
return {{{"B"_mst}, Fragment::WRAP_V}};
488487
case 25:
489488
if (!allow_B) return {};
490-
return {{{B}, Fragment::WRAP_J}};
489+
return {{{"B"_mst}, Fragment::WRAP_J}};
491490
case 26:
492491
if (!allow_B) return {};
493-
return {{{B}, Fragment::WRAP_N}};
492+
return {{{"B"_mst}, Fragment::WRAP_N}};
494493
case 27: {
495494
if (!allow_B || !IsTapscript(script_ctx)) return {};
496495
const auto k = provider.ConsumeIntegral<uint16_t>();
@@ -528,23 +527,20 @@ struct SmartInfo
528527
{
529528
/* Construct a set of interesting type requirements to reason with (sections of BKVWzondu). */
530529
std::vector<Type> types;
531-
static constexpr auto B_mst{"B"_mst}, K_mst{"K"_mst}, V_mst{"V"_mst}, W_mst{"W"_mst};
532-
static constexpr auto d_mst{"d"_mst}, n_mst{"n"_mst}, o_mst{"o"_mst}, u_mst{"u"_mst}, z_mst{"z"_mst};
533-
static constexpr auto NONE_mst{""_mst};
534530
for (int base = 0; base < 4; ++base) { /* select from B,K,V,W */
535-
Type type_base = base == 0 ? B_mst : base == 1 ? K_mst : base == 2 ? V_mst : W_mst;
531+
Type type_base = base == 0 ? "B"_mst : base == 1 ? "K"_mst : base == 2 ? "V"_mst : "W"_mst;
536532
for (int zo = 0; zo < 3; ++zo) { /* select from z,o,(none) */
537-
Type type_zo = zo == 0 ? z_mst : zo == 1 ? o_mst : NONE_mst;
533+
Type type_zo = zo == 0 ? "z"_mst : zo == 1 ? "o"_mst : ""_mst;
538534
for (int n = 0; n < 2; ++n) { /* select from (none),n */
539535
if (zo == 0 && n == 1) continue; /* z conflicts with n */
540536
if (base == 3 && n == 1) continue; /* W conflicts with n */
541-
Type type_n = n == 0 ? NONE_mst : n_mst;
537+
Type type_n = n == 0 ? ""_mst : "n"_mst;
542538
for (int d = 0; d < 2; ++d) { /* select from (none),d */
543539
if (base == 2 && d == 1) continue; /* V conflicts with d */
544-
Type type_d = d == 0 ? NONE_mst : d_mst;
540+
Type type_d = d == 0 ? ""_mst : "d"_mst;
545541
for (int u = 0; u < 2; ++u) { /* select from (none),u */
546542
if (base == 2 && u == 1) continue; /* V conflicts with u */
547-
Type type_u = u == 0 ? NONE_mst : u_mst;
543+
Type type_u = u == 0 ? ""_mst : "u"_mst;
548544
Type type = type_base | type_zo | type_n | type_d | type_u;
549545
types.push_back(type);
550546
}
@@ -686,7 +682,7 @@ struct SmartInfo
686682
/* Find which types are useful. The fuzzer logic only cares about constructing
687683
* B,V,K,W nodes, so any type that isn't needed in any recipe (directly or
688684
* indirectly) for the construction of those is uninteresting. */
689-
std::set<Type> useful_types{B_mst, V_mst, K_mst, W_mst};
685+
std::set<Type> useful_types{"B"_mst, "V"_mst, "K"_mst, "W"_mst};
690686
// Find the transitive closure by adding types until the set of types does not change.
691687
while (true) {
692688
size_t set_size = useful_types.size();

0 commit comments

Comments
 (0)