Skip to content

Commit 25e95f9

Browse files
committed
Merge/generalize IsValidMultisigKeyCount/GetMultisigKeyCount
1 parent 16781e1 commit 25e95f9

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

src/script/standard.cpp

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -96,47 +96,45 @@ static constexpr bool IsPushdataOp(opcodetype opcode)
9696
return opcode > OP_FALSE && opcode <= OP_PUSHDATA4;
9797
}
9898

99-
static constexpr bool IsValidMultisigKeyCount(int n_keys)
100-
{
101-
return n_keys > 0 && n_keys <= MAX_PUBKEYS_PER_MULTISIG;
102-
}
103-
104-
static bool GetMultisigKeyCount(opcodetype opcode, valtype data, int& count)
99+
/** Retrieve a minimally-encoded number in range [min,max] from an (opcode, data) pair,
100+
* whether it's OP_n or through a push. */
101+
static std::optional<int> GetScriptNumber(opcodetype opcode, valtype data, int min, int max)
105102
{
103+
int count;
106104
if (IsSmallInteger(opcode)) {
107105
count = CScript::DecodeOP_N(opcode);
108-
return IsValidMultisigKeyCount(count);
109-
}
110-
111-
if (IsPushdataOp(opcode)) {
112-
if (!CheckMinimalPush(data, opcode)) return false;
106+
} else if (IsPushdataOp(opcode)) {
107+
if (!CheckMinimalPush(data, opcode)) return {};
113108
try {
114109
count = CScriptNum(data, /* fRequireMinimal = */ true).getint();
115-
return IsValidMultisigKeyCount(count);
116110
} catch (const scriptnum_error&) {
117-
return false;
111+
return {};
118112
}
113+
} else {
114+
return {};
119115
}
120-
121-
return false;
116+
if (count < min || count > max) return {};
117+
return count;
122118
}
123119

124120
static bool MatchMultisig(const CScript& script, int& required_sigs, std::vector<valtype>& pubkeys)
125121
{
126122
opcodetype opcode;
127123
valtype data;
128-
int num_keys;
129124

130125
CScript::const_iterator it = script.begin();
131126
if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false;
132127

133-
if (!script.GetOp(it, opcode, data) || !GetMultisigKeyCount(opcode, data, required_sigs)) return false;
128+
if (!script.GetOp(it, opcode, data)) return false;
129+
auto req_sigs = GetScriptNumber(opcode, data, 1, MAX_PUBKEYS_PER_MULTISIG);
130+
if (!req_sigs) return false;
131+
required_sigs = *req_sigs;
134132
while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) {
135133
pubkeys.emplace_back(std::move(data));
136134
}
137-
if (!GetMultisigKeyCount(opcode, data, num_keys)) return false;
138-
139-
if (pubkeys.size() != static_cast<unsigned long>(num_keys) || num_keys < required_sigs) return false;
135+
auto num_keys = GetScriptNumber(opcode, data, required_sigs, MAX_PUBKEYS_PER_MULTISIG);
136+
if (!num_keys) return false;
137+
if (pubkeys.size() != static_cast<unsigned long>(*num_keys)) return false;
140138

141139
return (it + 1 == script.end());
142140
}

0 commit comments

Comments
 (0)