Skip to content

Commit 61a044a

Browse files
committed
Merge #13491: Improve handling of INVALID in IsMine
bb582a5 Add P2WSH destination helper and use it instead of manual hashing (Pieter Wuille) eaba1c1 Add additional unit tests for invalid IsMine combinations (Pieter Wuille) e6b9730 Do not expose invalidity from IsMine (Pieter Wuille) Pull request description: This improves the handling of INVALID in IsMine: * Extra INVALID conditions were added to `IsMine` (following https://github.com/bitcoin/bitcoin/pull/13142/files#r185349057), but these were untested. Add unit tests for them. * In bitcoin/bitcoin#13142 (comment) it was suggested to merge `isInvalid` into the return status. This PR takes a different approach, and removes the `isInvalid` entirely. It was only ever used inside tests, as normal users of IsMine don't care about the reason for non-mine-ness, only whether it is or not. As the unit tests are extensive enough, it seems sufficient to have a black box text (with tests for both compressed and uncompressed keys). Some addition code simplification is done as well. Tree-SHA512: 3267f8846f3fa4e994f57504b155b0e1bbdf13808c4c04dab7c6886c2c0b88716169cee9c5b350513297e0ca2a00812e3401acf30ac9cde5d892f9fb59ad7fef
2 parents b9ded73 + bb582a5 commit 61a044a

File tree

7 files changed

+125
-161
lines changed

7 files changed

+125
-161
lines changed

src/rpc/rawtransaction.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -637,9 +637,7 @@ static UniValue decodescript(const JSONRPCRequest& request)
637637
} else {
638638
// Scripts that are not fit for P2WPKH are encoded as P2WSH.
639639
// Newer segwit program versions should be considered when then become available.
640-
uint256 scriptHash;
641-
CSHA256().Write(script.data(), script.size()).Finalize(scriptHash.begin());
642-
segwitScr = GetScriptForDestination(WitnessV0ScriptHash(scriptHash));
640+
segwitScr = GetScriptForDestination(WitnessV0ScriptHash(script));
643641
}
644642
ScriptPubKeyToUniv(segwitScr, sr, true);
645643
sr.pushKV("p2sh-segwit", EncodeDestination(CScriptID(segwitScr)));

src/script/ismine.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ enum class IsMineResult
3838
NO = 0, //! Not ours
3939
WATCH_ONLY = 1, //! Included in watch-only balance
4040
SPENDABLE = 2, //! Included in all balances
41-
INVALID = 3, //! Not spendable by anyone
41+
INVALID = 3, //! Not spendable by anyone (uncompressed pubkey in segwit, P2SH inside P2SH or witness, witness inside witness)
4242
};
4343

4444
bool PermitsUncompressed(IsMineSigVersion sigversion)
@@ -173,12 +173,10 @@ IsMineResult IsMineInner(const CKeyStore& keystore, const CScript& scriptPubKey,
173173

174174
} // namespace
175175

176-
isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, bool& isInvalid)
176+
isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey)
177177
{
178-
isInvalid = false;
179178
switch (IsMineInner(keystore, scriptPubKey, IsMineSigVersion::TOP)) {
180179
case IsMineResult::INVALID:
181-
isInvalid = true;
182180
case IsMineResult::NO:
183181
return ISMINE_NO;
184182
case IsMineResult::WATCH_ONLY:
@@ -189,12 +187,6 @@ isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, bool&
189187
assert(false);
190188
}
191189

192-
isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey)
193-
{
194-
bool isInvalid = false;
195-
return IsMine(keystore, scriptPubKey, isInvalid);
196-
}
197-
198190
isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest)
199191
{
200192
CScript script = GetScriptForDestination(dest);

src/script/ismine.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ enum isminetype
2424
/** used for bitflags of isminetype */
2525
typedef uint8_t isminefilter;
2626

27-
/* isInvalid becomes true when the script is found invalid by consensus or policy. This will terminate the recursion
28-
* and return ISMINE_NO immediately, as an invalid script should never be considered as "mine". This is needed as
29-
* different SIGVERSION may have different network rules. Currently the only use of isInvalid is indicate uncompressed
30-
* keys in SigVersion::WITNESS_V0 script, but could also be used in similar cases in the future
31-
*/
32-
isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, bool& isInvalid);
3327
isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
3428
isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest);
3529

src/script/standard.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <script/standard.h>
77

8+
#include <crypto/sha256.h>
89
#include <pubkey.h>
910
#include <script/script.h>
1011
#include <util.h>
@@ -18,6 +19,11 @@ unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
1819

1920
CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
2021

22+
WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
23+
{
24+
CSHA256().Write(in.data(), in.size()).Finalize(begin());
25+
}
26+
2127
const char* GetTxnOutputType(txnouttype t)
2228
{
2329
switch (t)
@@ -329,9 +335,7 @@ CScript GetScriptForWitness(const CScript& redeemscript)
329335
return GetScriptForDestination(WitnessV0KeyHash(vSolutions[0]));
330336
}
331337
}
332-
uint256 hash;
333-
CSHA256().Write(&redeemscript[0], redeemscript.size()).Finalize(hash.begin());
334-
return GetScriptForDestination(WitnessV0ScriptHash(hash));
338+
return GetScriptForDestination(WitnessV0ScriptHash(redeemscript));
335339
}
336340

337341
bool IsValidDestination(const CTxDestination& dest) {

src/script/standard.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct WitnessV0ScriptHash : public uint256
7777
{
7878
WitnessV0ScriptHash() : uint256() {}
7979
explicit WitnessV0ScriptHash(const uint256& hash) : uint256(hash) {}
80+
explicit WitnessV0ScriptHash(const CScript& script);
8081
using uint256::uint256;
8182
};
8283

0 commit comments

Comments
 (0)