@@ -29,13 +29,25 @@ unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
29
29
return nResult;
30
30
}
31
31
32
- isminetype IsMine (const CKeyStore &keystore, const CTxDestination& dest)
32
+ isminetype IsMine (const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion sigversion)
33
+ {
34
+ bool isInvalid = false ;
35
+ return IsMine (keystore, scriptPubKey, isInvalid, sigversion);
36
+ }
37
+
38
+ isminetype IsMine (const CKeyStore& keystore, const CTxDestination& dest, SigVersion sigversion)
39
+ {
40
+ bool isInvalid = false ;
41
+ return IsMine (keystore, dest, isInvalid, sigversion);
42
+ }
43
+
44
+ isminetype IsMine (const CKeyStore &keystore, const CTxDestination& dest, bool & isInvalid, SigVersion sigversion)
33
45
{
34
46
CScript script = GetScriptForDestination (dest);
35
- return IsMine (keystore, script);
47
+ return IsMine (keystore, script, isInvalid, sigversion );
36
48
}
37
49
38
- isminetype IsMine (const CKeyStore &keystore, const CScript& scriptPubKey)
50
+ isminetype IsMine (const CKeyStore &keystore, const CScript& scriptPubKey, bool & isInvalid, SigVersion sigversion )
39
51
{
40
52
vector<valtype> vSolutions;
41
53
txnouttype whichType;
@@ -53,12 +65,35 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
53
65
break ;
54
66
case TX_PUBKEY:
55
67
keyID = CPubKey (vSolutions[0 ]).GetID ();
68
+ if (sigversion != SIGVERSION_BASE && vSolutions[0 ].size () != 33 ) {
69
+ isInvalid = true ;
70
+ return ISMINE_NO;
71
+ }
56
72
if (keystore.HaveKey (keyID))
57
73
return ISMINE_SPENDABLE;
58
74
break ;
59
- case TX_PUBKEYHASH:
60
75
case TX_WITNESS_V0_KEYHASH:
76
+ {
77
+ if (!keystore.HaveCScript (CScriptID (CScript () << OP_0 << vSolutions[0 ]))) {
78
+ // We do not support bare witness outputs unless the P2SH version of it would be
79
+ // acceptable as well. This protects against matching before segwit activates.
80
+ // This also applies to the P2WSH case.
81
+ break ;
82
+ }
83
+ isminetype ret = ::IsMine (keystore, GetScriptForDestination (CKeyID (uint160 (vSolutions[0 ]))), isInvalid, SIGVERSION_WITNESS_V0);
84
+ if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
85
+ return ret;
86
+ break ;
87
+ }
88
+ case TX_PUBKEYHASH:
61
89
keyID = CKeyID (uint160 (vSolutions[0 ]));
90
+ if (sigversion != SIGVERSION_BASE) {
91
+ CPubKey pubkey;
92
+ if (keystore.GetPubKey (keyID, pubkey) && !pubkey.IsCompressed ()) {
93
+ isInvalid = true ;
94
+ return ISMINE_NO;
95
+ }
96
+ }
62
97
if (keystore.HaveKey (keyID))
63
98
return ISMINE_SPENDABLE;
64
99
break ;
@@ -67,21 +102,24 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
67
102
CScriptID scriptID = CScriptID (uint160 (vSolutions[0 ]));
68
103
CScript subscript;
69
104
if (keystore.GetCScript (scriptID, subscript)) {
70
- isminetype ret = IsMine (keystore, subscript);
71
- if (ret == ISMINE_SPENDABLE)
105
+ isminetype ret = IsMine (keystore, subscript, isInvalid );
106
+ if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid) )
72
107
return ret;
73
108
}
74
109
break ;
75
110
}
76
111
case TX_WITNESS_V0_SCRIPTHASH:
77
112
{
113
+ if (!keystore.HaveCScript (CScriptID (CScript () << OP_0 << vSolutions[0 ]))) {
114
+ break ;
115
+ }
78
116
uint160 hash;
79
117
CRIPEMD160 ().Write (&vSolutions[0 ][0 ], vSolutions[0 ].size ()).Finalize (hash.begin ());
80
118
CScriptID scriptID = CScriptID (hash);
81
119
CScript subscript;
82
120
if (keystore.GetCScript (scriptID, subscript)) {
83
- isminetype ret = IsMine (keystore, subscript);
84
- if (ret == ISMINE_SPENDABLE)
121
+ isminetype ret = IsMine (keystore, subscript, isInvalid, SIGVERSION_WITNESS_V0 );
122
+ if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid) )
85
123
return ret;
86
124
}
87
125
break ;
@@ -95,6 +133,14 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
95
133
// them) enable spend-out-from-under-you attacks, especially
96
134
// in shared-wallet situations.
97
135
vector<valtype> keys (vSolutions.begin ()+1 , vSolutions.begin ()+vSolutions.size ()-1 );
136
+ if (sigversion != SIGVERSION_BASE) {
137
+ for (size_t i = 0 ; i < keys.size (); i++) {
138
+ if (keys[i].size () != 33 ) {
139
+ isInvalid = true ;
140
+ return ISMINE_NO;
141
+ }
142
+ }
143
+ }
98
144
if (HaveKeys (keys, keystore) == keys.size ())
99
145
return ISMINE_SPENDABLE;
100
146
break ;
0 commit comments