Move ismine to wallet module

This commit is contained in:
Andrew Chow 2019-06-06 09:53:16 +02:00
parent 413e438ea9
commit 7c611e2000
13 changed files with 395 additions and 376 deletions

View File

@ -181,7 +181,6 @@ BITCOIN_CORE_H = \
rpc/util.h \ rpc/util.h \
scheduler.h \ scheduler.h \
script/descriptor.h \ script/descriptor.h \
script/ismine.h \
script/sigcache.h \ script/sigcache.h \
script/sign.h \ script/sign.h \
script/standard.h \ script/standard.h \
@ -223,6 +222,7 @@ BITCOIN_CORE_H = \
wallet/db.h \ wallet/db.h \
wallet/feebumper.h \ wallet/feebumper.h \
wallet/fees.h \ wallet/fees.h \
wallet/ismine.h \
wallet/load.h \ wallet/load.h \
wallet/psbtwallet.h \ wallet/psbtwallet.h \
wallet/rpcwallet.h \ wallet/rpcwallet.h \
@ -328,6 +328,7 @@ libbitcoin_wallet_a_SOURCES = \
wallet/db.cpp \ wallet/db.cpp \
wallet/feebumper.cpp \ wallet/feebumper.cpp \
wallet/fees.cpp \ wallet/fees.cpp \
wallet/ismine.cpp \
wallet/load.cpp \ wallet/load.cpp \
wallet/psbtwallet.cpp \ wallet/psbtwallet.cpp \
wallet/rpcdump.cpp \ wallet/rpcdump.cpp \
@ -458,7 +459,6 @@ libbitcoin_common_a_SOURCES = \
rpc/util.cpp \ rpc/util.cpp \
scheduler.cpp \ scheduler.cpp \
script/descriptor.cpp \ script/descriptor.cpp \
script/ismine.cpp \
script/sign.cpp \ script/sign.cpp \
script/standard.cpp \ script/standard.cpp \
versionbitsinfo.cpp \ versionbitsinfo.cpp \

View File

@ -167,7 +167,8 @@ BITCOIN_TESTS += \
wallet/test/wallet_tests.cpp \ wallet/test/wallet_tests.cpp \
wallet/test/wallet_crypto_tests.cpp \ wallet/test/wallet_crypto_tests.cpp \
wallet/test/coinselector_tests.cpp \ wallet/test/coinselector_tests.cpp \
wallet/test/init_tests.cpp wallet/test/init_tests.cpp \
wallet/test/ismine_tests.cpp
BITCOIN_TEST_SUITE += \ BITCOIN_TEST_SUITE += \
wallet/test/wallet_test_fixture.cpp \ wallet/test/wallet_test_fixture.cpp \

View File

@ -11,7 +11,6 @@
#include <policy/feerate.h> #include <policy/feerate.h>
#include <policy/fees.h> #include <policy/fees.h>
#include <primitives/transaction.h> #include <primitives/transaction.h>
#include <script/ismine.h>
#include <script/standard.h> #include <script/standard.h>
#include <support/allocators/secure.h> #include <support/allocators/secure.h>
#include <sync.h> #include <sync.h>
@ -20,6 +19,7 @@
#include <util/system.h> #include <util/system.h>
#include <wallet/feebumper.h> #include <wallet/feebumper.h>
#include <wallet/fees.h> #include <wallet/fees.h>
#include <wallet/ismine.h>
#include <wallet/rpcwallet.h> #include <wallet/rpcwallet.h>
#include <wallet/load.h> #include <wallet/load.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>

View File

@ -7,7 +7,6 @@
#include <amount.h> // For CAmount #include <amount.h> // For CAmount
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation) #include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
#include <script/ismine.h> // For isminefilter, isminetype
#include <script/standard.h> // For CTxDestination #include <script/standard.h> // For CTxDestination
#include <support/allocators/secure.h> // For SecureString #include <support/allocators/secure.h> // For SecureString
#include <ui_interface.h> // For ChangeType #include <ui_interface.h> // For ChangeType
@ -25,7 +24,10 @@ class CCoinControl;
class CFeeRate; class CFeeRate;
class CKey; class CKey;
class CWallet; class CWallet;
enum isminetype : unsigned int;
enum class FeeReason; enum class FeeReason;
typedef uint8_t isminefilter;
enum class OutputType; enum class OutputType;
struct CRecipient; struct CRecipient;

View File

@ -21,6 +21,7 @@
#include <timedata.h> #include <timedata.h>
#include <util/system.h> #include <util/system.h>
#include <policy/policy.h> #include <policy/policy.h>
#include <wallet/ismine.h>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>

View File

@ -7,6 +7,7 @@
#include <chain.h> #include <chain.h>
#include <interfaces/wallet.h> #include <interfaces/wallet.h>
#include <key_io.h> #include <key_io.h>
#include <wallet/ismine.h>
#include <stdint.h> #include <stdint.h>

View File

@ -11,7 +11,6 @@
#include <script/script_error.h> #include <script/script_error.h>
#include <policy/settings.h> #include <policy/settings.h>
#include <script/sign.h> #include <script/sign.h>
#include <script/ismine.h>
#include <test/setup_common.h> #include <test/setup_common.h>
#include <vector> #include <vector>
@ -98,7 +97,6 @@ BOOST_AUTO_TEST_CASE(sign)
txTo[i].vin[0].prevout.n = i; txTo[i].vin[0].prevout.n = i;
txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vin[0].prevout.hash = txFrom.GetHash();
txTo[i].vout[0].nValue = 1; txTo[i].vout[0].nValue = 1;
BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
} }
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
@ -195,7 +193,6 @@ BOOST_AUTO_TEST_CASE(set)
txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vin[0].prevout.hash = txFrom.GetHash();
txTo[i].vout[0].nValue = 1*CENT; txTo[i].vout[0].nValue = 1*CENT;
txTo[i].vout[0].scriptPubKey = inner[i]; txTo[i].vout[0].scriptPubKey = inner[i];
BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
} }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {

View File

@ -4,7 +4,6 @@
#include <key.h> #include <key.h>
#include <keystore.h> #include <keystore.h>
#include <script/ismine.h>
#include <script/script.h> #include <script/script.h>
#include <script/script_error.h> #include <script/script_error.h>
#include <script/standard.h> #include <script/standard.h>
@ -372,364 +371,4 @@ BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
BOOST_CHECK(result == expected); BOOST_CHECK(result == expected);
} }
BOOST_AUTO_TEST_CASE(script_standard_IsMine)
{
CKey keys[2];
CPubKey pubkeys[2];
for (int i = 0; i < 2; i++) {
keys[i].MakeNewKey(true);
pubkeys[i] = keys[i].GetPubKey();
}
CKey uncompressedKey;
uncompressedKey.MakeNewKey(false);
CPubKey uncompressedPubkey = uncompressedKey.GetPubKey();
CScript scriptPubKey;
isminetype result;
// P2PK compressed
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForRawPubKey(pubkeys[0]);
// Keystore does not have key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2PK uncompressed
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey);
// Keystore does not have key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key
BOOST_CHECK(keystore.AddKey(uncompressedKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2PKH compressed
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForDestination(PKHash(pubkeys[0]));
// Keystore does not have key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2PKH uncompressed
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForDestination(PKHash(uncompressedPubkey));
// Keystore does not have key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key
BOOST_CHECK(keystore.AddKey(uncompressedKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2SH
{
CBasicKeyStore keystore;
CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0]));
scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
// Keystore does not have redeemScript or key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has redeemScript but no key
BOOST_CHECK(keystore.AddCScript(redeemScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has redeemScript and key
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// (P2PKH inside) P2SH inside P2SH (invalid)
{
CBasicKeyStore keystore;
CScript redeemscript_inner = GetScriptForDestination(PKHash(pubkeys[0]));
CScript redeemscript = GetScriptForDestination(ScriptHash(redeemscript_inner));
scriptPubKey = GetScriptForDestination(ScriptHash(redeemscript));
BOOST_CHECK(keystore.AddCScript(redeemscript));
BOOST_CHECK(keystore.AddCScript(redeemscript_inner));
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// (P2PKH inside) P2SH inside P2WSH (invalid)
{
CBasicKeyStore keystore;
CScript redeemscript = GetScriptForDestination(PKHash(pubkeys[0]));
CScript witnessscript = GetScriptForDestination(ScriptHash(redeemscript));
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
BOOST_CHECK(keystore.AddCScript(witnessscript));
BOOST_CHECK(keystore.AddCScript(redeemscript));
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// P2WPKH inside P2WSH (invalid)
{
CBasicKeyStore keystore;
CScript witnessscript = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0])));
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
BOOST_CHECK(keystore.AddCScript(witnessscript));
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// (P2PKH inside) P2WSH inside P2WSH (invalid)
{
CBasicKeyStore keystore;
CScript witnessscript_inner = GetScriptForDestination(PKHash(pubkeys[0]));
CScript witnessscript = GetScriptForDestination(WitnessV0ScriptHash(witnessscript_inner));
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
BOOST_CHECK(keystore.AddCScript(witnessscript_inner));
BOOST_CHECK(keystore.AddCScript(witnessscript));
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// P2WPKH compressed
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0])));
// Keystore implicitly has key and P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2WPKH uncompressed
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(uncompressedKey));
scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(uncompressedPubkey)));
// Keystore has key, but no P2SH redeemScript
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key and P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// scriptPubKey multisig
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
// Keystore does not have any keys
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has 1/2 keys
BOOST_CHECK(keystore.AddKey(uncompressedKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has 2/2 keys
BOOST_CHECK(keystore.AddKey(keys[1]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has 2/2 keys and the script
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// P2SH multisig
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(uncompressedKey));
BOOST_CHECK(keystore.AddKey(keys[1]));
CScript redeemScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
// Keystore has no redeemScript
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has redeemScript
BOOST_CHECK(keystore.AddCScript(redeemScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2WSH multisig with compressed keys
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
BOOST_CHECK(keystore.AddKey(keys[1]));
CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
// Keystore has keys, but no witnessScript or P2SH redeemScript
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys and witnessScript, but no P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(witnessScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys, witnessScript, P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2WSH multisig with uncompressed key
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(uncompressedKey));
BOOST_CHECK(keystore.AddKey(keys[1]));
CScript witnessScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
// Keystore has keys, but no witnessScript or P2SH redeemScript
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys and witnessScript, but no P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(witnessScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys, witnessScript, P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// P2WSH multisig wrapped in P2SH
{
CBasicKeyStore keystore;
CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
// Keystore has no witnessScript, P2SH redeemScript, or keys
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has witnessScript and P2SH redeemScript, but no keys
BOOST_CHECK(keystore.AddCScript(redeemScript));
BOOST_CHECK(keystore.AddCScript(witnessScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys, witnessScript, P2SH redeemScript
BOOST_CHECK(keystore.AddKey(keys[0]));
BOOST_CHECK(keystore.AddKey(keys[1]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// OP_RETURN
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey.clear();
scriptPubKey << OP_RETURN << ToByteVector(pubkeys[0]);
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// witness unspendable
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey.clear();
scriptPubKey << OP_0 << ToByteVector(ParseHex("aabb"));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// witness unknown
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey.clear();
scriptPubKey << OP_16 << ToByteVector(ParseHex("aabb"));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// Nonstandard
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey.clear();
scriptPubKey << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -3,7 +3,7 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <script/ismine.h> #include <wallet/ismine.h>
#include <key.h> #include <key.h>
#include <keystore.h> #include <keystore.h>

View File

@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_ISMINE_H #ifndef BITCOIN_WALLET_ISMINE_H
#define BITCOIN_SCRIPT_ISMINE_H #define BITCOIN_WALLET_ISMINE_H
#include <script/standard.h> #include <script/standard.h>
@ -15,7 +15,7 @@ class CKeyStore;
class CScript; class CScript;
/** IsMine() return codes */ /** IsMine() return codes */
enum isminetype enum isminetype : unsigned int
{ {
ISMINE_NO = 0, ISMINE_NO = 0,
ISMINE_WATCH_ONLY = 1 << 0, ISMINE_WATCH_ONLY = 1 << 0,
@ -50,4 +50,4 @@ struct CachableAmount
} }
}; };
#endif // BITCOIN_SCRIPT_ISMINE_H #endif // BITCOIN_WALLET_ISMINE_H

View File

@ -0,0 +1,378 @@
// Copyright (c) 2017-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <key.h>
#include <keystore.h>
#include <script/script.h>
#include <script/script_error.h>
#include <script/standard.h>
#include <test/setup_common.h>
#include <wallet/ismine.h>
#include <boost/test/unit_test.hpp>
BOOST_FIXTURE_TEST_SUITE(ismine_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(ismine_standard)
{
CKey keys[2];
CPubKey pubkeys[2];
for (int i = 0; i < 2; i++) {
keys[i].MakeNewKey(true);
pubkeys[i] = keys[i].GetPubKey();
}
CKey uncompressedKey;
uncompressedKey.MakeNewKey(false);
CPubKey uncompressedPubkey = uncompressedKey.GetPubKey();
CScript scriptPubKey;
isminetype result;
// P2PK compressed
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForRawPubKey(pubkeys[0]);
// Keystore does not have key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2PK uncompressed
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey);
// Keystore does not have key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key
BOOST_CHECK(keystore.AddKey(uncompressedKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2PKH compressed
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForDestination(PKHash(pubkeys[0]));
// Keystore does not have key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2PKH uncompressed
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForDestination(PKHash(uncompressedPubkey));
// Keystore does not have key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key
BOOST_CHECK(keystore.AddKey(uncompressedKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2SH
{
CBasicKeyStore keystore;
CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0]));
scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
// Keystore does not have redeemScript or key
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has redeemScript but no key
BOOST_CHECK(keystore.AddCScript(redeemScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has redeemScript and key
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// (P2PKH inside) P2SH inside P2SH (invalid)
{
CBasicKeyStore keystore;
CScript redeemscript_inner = GetScriptForDestination(PKHash(pubkeys[0]));
CScript redeemscript = GetScriptForDestination(ScriptHash(redeemscript_inner));
scriptPubKey = GetScriptForDestination(ScriptHash(redeemscript));
BOOST_CHECK(keystore.AddCScript(redeemscript));
BOOST_CHECK(keystore.AddCScript(redeemscript_inner));
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// (P2PKH inside) P2SH inside P2WSH (invalid)
{
CBasicKeyStore keystore;
CScript redeemscript = GetScriptForDestination(PKHash(pubkeys[0]));
CScript witnessscript = GetScriptForDestination(ScriptHash(redeemscript));
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
BOOST_CHECK(keystore.AddCScript(witnessscript));
BOOST_CHECK(keystore.AddCScript(redeemscript));
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// P2WPKH inside P2WSH (invalid)
{
CBasicKeyStore keystore;
CScript witnessscript = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0])));
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
BOOST_CHECK(keystore.AddCScript(witnessscript));
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// (P2PKH inside) P2WSH inside P2WSH (invalid)
{
CBasicKeyStore keystore;
CScript witnessscript_inner = GetScriptForDestination(PKHash(pubkeys[0]));
CScript witnessscript = GetScriptForDestination(WitnessV0ScriptHash(witnessscript_inner));
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
BOOST_CHECK(keystore.AddCScript(witnessscript_inner));
BOOST_CHECK(keystore.AddCScript(witnessscript));
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
BOOST_CHECK(keystore.AddKey(keys[0]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// P2WPKH compressed
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(pubkeys[0])));
// Keystore implicitly has key and P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2WPKH uncompressed
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(uncompressedKey));
scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(PKHash(uncompressedPubkey)));
// Keystore has key, but no P2SH redeemScript
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has key and P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// scriptPubKey multisig
{
CBasicKeyStore keystore;
scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
// Keystore does not have any keys
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has 1/2 keys
BOOST_CHECK(keystore.AddKey(uncompressedKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has 2/2 keys
BOOST_CHECK(keystore.AddKey(keys[1]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has 2/2 keys and the script
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// P2SH multisig
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(uncompressedKey));
BOOST_CHECK(keystore.AddKey(keys[1]));
CScript redeemScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
// Keystore has no redeemScript
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has redeemScript
BOOST_CHECK(keystore.AddCScript(redeemScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2WSH multisig with compressed keys
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
BOOST_CHECK(keystore.AddKey(keys[1]));
CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
// Keystore has keys, but no witnessScript or P2SH redeemScript
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys and witnessScript, but no P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(witnessScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys, witnessScript, P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// P2WSH multisig with uncompressed key
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(uncompressedKey));
BOOST_CHECK(keystore.AddKey(keys[1]));
CScript witnessScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
// Keystore has keys, but no witnessScript or P2SH redeemScript
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys and witnessScript, but no P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(witnessScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys, witnessScript, P2SH redeemScript
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// P2WSH multisig wrapped in P2SH
{
CBasicKeyStore keystore;
CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
// Keystore has no witnessScript, P2SH redeemScript, or keys
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has witnessScript and P2SH redeemScript, but no keys
BOOST_CHECK(keystore.AddCScript(redeemScript));
BOOST_CHECK(keystore.AddCScript(witnessScript));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
// Keystore has keys, witnessScript, P2SH redeemScript
BOOST_CHECK(keystore.AddKey(keys[0]));
BOOST_CHECK(keystore.AddKey(keys[1]));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
}
// OP_RETURN
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey.clear();
scriptPubKey << OP_RETURN << ToByteVector(pubkeys[0]);
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// witness unspendable
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey.clear();
scriptPubKey << OP_0 << ToByteVector(ParseHex("aabb"));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// witness unknown
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey.clear();
scriptPubKey << OP_16 << ToByteVector(ParseHex("aabb"));
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
// Nonstandard
{
CBasicKeyStore keystore;
BOOST_CHECK(keystore.AddKey(keys[0]));
scriptPubKey.clear();
scriptPubKey << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
result = IsMine(keystore, scriptPubKey);
BOOST_CHECK_EQUAL(result, ISMINE_NO);
}
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -11,7 +11,6 @@
#include <interfaces/handler.h> #include <interfaces/handler.h>
#include <outputtype.h> #include <outputtype.h>
#include <policy/feerate.h> #include <policy/feerate.h>
#include <script/ismine.h>
#include <script/sign.h> #include <script/sign.h>
#include <streams.h> #include <streams.h>
#include <tinyformat.h> #include <tinyformat.h>
@ -21,6 +20,7 @@
#include <validationinterface.h> #include <validationinterface.h>
#include <wallet/coinselection.h> #include <wallet/coinselection.h>
#include <wallet/crypter.h> #include <wallet/crypter.h>
#include <wallet/ismine.h>
#include <wallet/walletdb.h> #include <wallet/walletdb.h>
#include <wallet/walletutil.h> #include <wallet/walletutil.h>

View File

@ -5,7 +5,7 @@
#ifndef BITCOIN_WALLET_WALLETTOOL_H #ifndef BITCOIN_WALLET_WALLETTOOL_H
#define BITCOIN_WALLET_WALLETTOOL_H #define BITCOIN_WALLET_WALLETTOOL_H
#include <script/ismine.h> #include <wallet/ismine.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
namespace WalletTool { namespace WalletTool {