13
13
14
14
typedef std::vector<unsigned char > valtype;
15
15
16
+ /* *
17
+ * This is an enum that tracks the execution context of a script, similar to
18
+ * SigVersion in script/interpreter. It is separate however because we want to
19
+ * distinguish between top-level scriptPubKey execution and P2SH redeemScript
20
+ * execution (a distinction that has no impact on consensus rules).
21
+ */
16
22
enum class IsMineSigVersion
17
23
{
18
- BASE = 0 ,
19
- WITNESS_V0 = 1
24
+ TOP = 0 , // ! scriptPubKey execution
25
+ P2SH = 1 , // ! P2SH redeemScript
26
+ WITNESS_V0 = 2 // ! P2WSH witness script execution
20
27
};
21
28
29
+ static bool PermitsUncompressed (IsMineSigVersion sigversion)
30
+ {
31
+ return sigversion == IsMineSigVersion::TOP || sigversion == IsMineSigVersion::P2SH;
32
+ }
33
+
22
34
static bool HaveKeys (const std::vector<valtype>& pubkeys, const CKeyStore& keystore)
23
35
{
24
36
for (const valtype& pubkey : pubkeys) {
@@ -49,7 +61,7 @@ static isminetype IsMineInner(const CKeyStore& keystore, const CScript& scriptPu
49
61
break ;
50
62
case TX_PUBKEY:
51
63
keyID = CPubKey (vSolutions[0 ]).GetID ();
52
- if (sigversion != IsMineSigVersion::BASE && vSolutions[0 ].size () != 33 ) {
64
+ if (! PermitsUncompressed (sigversion) && vSolutions[0 ].size () != 33 ) {
53
65
isInvalid = true ;
54
66
return ISMINE_NO;
55
67
}
@@ -71,7 +83,7 @@ static isminetype IsMineInner(const CKeyStore& keystore, const CScript& scriptPu
71
83
}
72
84
case TX_PUBKEYHASH:
73
85
keyID = CKeyID (uint160 (vSolutions[0 ]));
74
- if (sigversion != IsMineSigVersion::BASE ) {
86
+ if (! PermitsUncompressed (sigversion) ) {
75
87
CPubKey pubkey;
76
88
if (keystore.GetPubKey (keyID, pubkey) && !pubkey.IsCompressed ()) {
77
89
isInvalid = true ;
@@ -86,7 +98,7 @@ static isminetype IsMineInner(const CKeyStore& keystore, const CScript& scriptPu
86
98
CScriptID scriptID = CScriptID (uint160 (vSolutions[0 ]));
87
99
CScript subscript;
88
100
if (keystore.GetCScript (scriptID, subscript)) {
89
- isminetype ret = IsMineInner (keystore, subscript, isInvalid, IsMineSigVersion::BASE );
101
+ isminetype ret = IsMineInner (keystore, subscript, isInvalid, IsMineSigVersion::P2SH );
90
102
if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
91
103
return ret;
92
104
}
@@ -117,7 +129,7 @@ static isminetype IsMineInner(const CKeyStore& keystore, const CScript& scriptPu
117
129
// them) enable spend-out-from-under-you attacks, especially
118
130
// in shared-wallet situations.
119
131
std::vector<valtype> keys (vSolutions.begin ()+1 , vSolutions.begin ()+vSolutions.size ()-1 );
120
- if (sigversion != IsMineSigVersion::BASE ) {
132
+ if (! PermitsUncompressed (sigversion) ) {
121
133
for (size_t i = 0 ; i < keys.size (); i++) {
122
134
if (keys[i].size () != 33 ) {
123
135
isInvalid = true ;
@@ -141,7 +153,7 @@ static isminetype IsMineInner(const CKeyStore& keystore, const CScript& scriptPu
141
153
142
154
isminetype IsMine (const CKeyStore& keystore, const CScript& scriptPubKey, bool & isInvalid)
143
155
{
144
- return IsMineInner (keystore, scriptPubKey, isInvalid, IsMineSigVersion::BASE );
156
+ return IsMineInner (keystore, scriptPubKey, isInvalid, IsMineSigVersion::TOP );
145
157
}
146
158
147
159
isminetype IsMine (const CKeyStore& keystore, const CScript& scriptPubKey)
0 commit comments