Merge #10583: [RPC] Split part of validateaddress into getaddressinfo
b22cce014
scripted-diff: validateaddress to getaddressinfo in tests (Andrew Chow)b98bfc5ed
Create getaddressinfo RPC and deprecate parts of validateaddress (Andrew Chow)1598f3230
[rpc] Move DescribeAddressVisitor to rpc/util (John Newbery)39633ecd5
[rpc] split wallet and non-wallet parts of DescribeAddressVisitor (John Newbery) Pull request description: This PR makes a new RPC command called `getaddressinfo` which relies on the wallet. It contains all of `validateaddress`'s address info stuff. Those parts in `validateaddress` have been marked as deprecated. The tests have been updated to use `getaddressinfo` except the `disablewallet` test which is the only test that actually uses `validateaddress` to validate an address. Tree-SHA512: ce00ed0f2416200b8de1e0a75e8517c024be0b6153457d302c3879b3491cce28191e7c29aed08ec7d2eeeadc62918f5c43a7cb79cd2e4b6d9291bd83ec31c852
This commit is contained in:
commit
8a98dfeebf
23 changed files with 427 additions and 302 deletions
|
@ -135,10 +135,10 @@ BITCOIN_CORE_H = \
|
|||
rpc/register.h \
|
||||
rpc/util.h \
|
||||
scheduler.h \
|
||||
script/ismine.h \
|
||||
script/sigcache.h \
|
||||
script/sign.h \
|
||||
script/standard.h \
|
||||
script/ismine.h \
|
||||
streams.h \
|
||||
support/allocators/secure.h \
|
||||
support/allocators/zeroafterfree.h \
|
||||
|
@ -216,7 +216,6 @@ libbitcoin_server_a_SOURCES = \
|
|||
rpc/safemode.cpp \
|
||||
rpc/server.cpp \
|
||||
script/sigcache.cpp \
|
||||
script/ismine.cpp \
|
||||
timedata.cpp \
|
||||
torcontrol.cpp \
|
||||
txdb.cpp \
|
||||
|
@ -333,6 +332,7 @@ libbitcoin_common_a_SOURCES = \
|
|||
policy/feerate.cpp \
|
||||
protocol.cpp \
|
||||
scheduler.cpp \
|
||||
script/ismine.cpp \
|
||||
script/sign.cpp \
|
||||
script/standard.cpp \
|
||||
warnings.cpp \
|
||||
|
@ -389,10 +389,10 @@ endif
|
|||
|
||||
bitcoind_LDADD = \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
$(LIBBITCOIN_WALLET) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBUNIVALUE) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_WALLET) \
|
||||
$(LIBBITCOIN_ZMQ) \
|
||||
$(LIBBITCOIN_CONSENSUS) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
|
|
|
@ -35,6 +35,7 @@ bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS
|
|||
bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
bench_bench_bitcoin_LDADD = \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
$(LIBBITCOIN_WALLET) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_CONSENSUS) \
|
||||
|
@ -51,7 +52,6 @@ endif
|
|||
|
||||
if ENABLE_WALLET
|
||||
bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp
|
||||
bench_bench_bitcoin_LDADD += $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CRYPTO)
|
||||
endif
|
||||
|
||||
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
|
|
207
src/rpc/misc.cpp
207
src/rpc/misc.cpp
|
@ -33,175 +33,33 @@
|
|||
|
||||
#include <univalue.h>
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
class DescribeAddressVisitor : public boost::static_visitor<UniValue>
|
||||
{
|
||||
public:
|
||||
CWallet * const pwallet;
|
||||
|
||||
explicit DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {}
|
||||
|
||||
void ProcessSubScript(const CScript& subscript, UniValue& obj, bool include_addresses = false) const
|
||||
{
|
||||
// Always present: script type and redeemscript
|
||||
txnouttype which_type;
|
||||
std::vector<std::vector<unsigned char>> solutions_data;
|
||||
Solver(subscript, which_type, solutions_data);
|
||||
obj.pushKV("script", GetTxnOutputType(which_type));
|
||||
obj.pushKV("hex", HexStr(subscript.begin(), subscript.end()));
|
||||
|
||||
CTxDestination embedded;
|
||||
UniValue a(UniValue::VARR);
|
||||
if (ExtractDestination(subscript, embedded)) {
|
||||
// Only when the script corresponds to an address.
|
||||
UniValue subobj = boost::apply_visitor(*this, embedded);
|
||||
subobj.pushKV("address", EncodeDestination(embedded));
|
||||
subobj.pushKV("scriptPubKey", HexStr(subscript.begin(), subscript.end()));
|
||||
// Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works.
|
||||
if (subobj.exists("pubkey")) obj.pushKV("pubkey", subobj["pubkey"]);
|
||||
obj.pushKV("embedded", std::move(subobj));
|
||||
if (include_addresses) a.push_back(EncodeDestination(embedded));
|
||||
} else if (which_type == TX_MULTISIG) {
|
||||
// Also report some information on multisig scripts (which do not have a corresponding address).
|
||||
// TODO: abstract out the common functionality between this logic and ExtractDestinations.
|
||||
obj.pushKV("sigsrequired", solutions_data[0][0]);
|
||||
UniValue pubkeys(UniValue::VARR);
|
||||
for (size_t i = 1; i < solutions_data.size() - 1; ++i) {
|
||||
CPubKey key(solutions_data[i].begin(), solutions_data[i].end());
|
||||
if (include_addresses) a.push_back(EncodeDestination(key.GetID()));
|
||||
pubkeys.push_back(HexStr(key.begin(), key.end()));
|
||||
}
|
||||
obj.pushKV("pubkeys", std::move(pubkeys));
|
||||
}
|
||||
|
||||
// The "addresses" field is confusing because it refers to public keys using their P2PKH address.
|
||||
// For that reason, only add the 'addresses' field when needed for backward compatibility. New applications
|
||||
// can use the 'embedded'->'address' field for P2SH or P2WSH wrapped addresses, and 'pubkeys' for
|
||||
// inspecting multisig participants.
|
||||
if (include_addresses) obj.pushKV("addresses", std::move(a));
|
||||
}
|
||||
|
||||
UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
|
||||
|
||||
UniValue operator()(const CKeyID &keyID) const {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CPubKey vchPubKey;
|
||||
obj.pushKV("isscript", false);
|
||||
obj.pushKV("iswitness", false);
|
||||
if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) {
|
||||
obj.pushKV("pubkey", HexStr(vchPubKey));
|
||||
obj.pushKV("iscompressed", vchPubKey.IsCompressed());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const CScriptID &scriptID) const {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CScript subscript;
|
||||
obj.pushKV("isscript", true);
|
||||
obj.pushKV("iswitness", false);
|
||||
if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
|
||||
ProcessSubScript(subscript, obj, true);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessV0KeyHash& id) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CPubKey pubkey;
|
||||
obj.pushKV("isscript", false);
|
||||
obj.pushKV("iswitness", true);
|
||||
obj.pushKV("witness_version", 0);
|
||||
obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
|
||||
if (pwallet && pwallet->GetPubKey(CKeyID(id), pubkey)) {
|
||||
obj.pushKV("pubkey", HexStr(pubkey));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessV0ScriptHash& id) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CScript subscript;
|
||||
obj.pushKV("isscript", true);
|
||||
obj.pushKV("iswitness", true);
|
||||
obj.pushKV("witness_version", 0);
|
||||
obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
|
||||
CRIPEMD160 hasher;
|
||||
uint160 hash;
|
||||
hasher.Write(id.begin(), 32).Finalize(hash.begin());
|
||||
if (pwallet && pwallet->GetCScript(CScriptID(hash), subscript)) {
|
||||
ProcessSubScript(subscript, obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessUnknown& id) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CScript subscript;
|
||||
obj.pushKV("iswitness", true);
|
||||
obj.pushKV("witness_version", (int)id.version);
|
||||
obj.pushKV("witness_program", HexStr(id.program, id.program + id.length));
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
UniValue validateaddress(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 1)
|
||||
throw std::runtime_error(
|
||||
"validateaddress \"address\"\n"
|
||||
"\nReturn information about the given bitcoin address.\n"
|
||||
"DEPRECATION WARNING: Parts of this command have been deprecated and moved to getaddressinfo. Clients must\n"
|
||||
"transition to using getaddressinfo to access this information before upgrading to v0.18. The following deprecated\n"
|
||||
"fields have moved to getaddressinfo and will only be shown here with -deprecatedrpc=validateaddress: ismine, iswatchonly,\n"
|
||||
"script, hex, pubkeys, sigsrequired, pubkey, addresses, embedded, iscompressed, account, timestamp, hdkeypath, kdmasterkeyid.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"address\" (string, required) The bitcoin address to validate\n"
|
||||
"1. \"address\" (string, required) The bitcoin address to validate\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
|
||||
" \"address\" : \"address\", (string) The bitcoin address validated\n"
|
||||
" \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
|
||||
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
|
||||
" \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
|
||||
" \"isscript\" : true|false, (boolean, optional) If the address is P2SH or P2WSH. Not included for unknown witness types.\n"
|
||||
" \"iswitness\" : true|false, (boolean) If the address is P2WPKH, P2WSH, or an unknown witness version\n"
|
||||
" \"witness_version\" : version (number, optional) For all witness output types, gives the version number.\n"
|
||||
" \"witness_program\" : \"hex\" (string, optional) For all witness output types, gives the script or key hash present in the address.\n"
|
||||
" \"script\" : \"type\" (string, optional) The output script type. Only if \"isscript\" is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown\n"
|
||||
" \"hex\" : \"hex\", (string, optional) The redeemscript for the P2SH or P2WSH address\n"
|
||||
" \"addresses\" (string, optional) Array of addresses associated with the known redeemscript (only if \"iswitness\" is false). This field is superseded by the \"pubkeys\" field and the address inside \"embedded\".\n"
|
||||
" [\n"
|
||||
" \"address\"\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
" \"pubkeys\" (string, optional) Array of pubkeys associated with the known redeemscript (only if \"script\" is \"multisig\")\n"
|
||||
" [\n"
|
||||
" \"pubkey\"\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
" \"sigsrequired\" : xxxxx (numeric, optional) Number of signatures required to spend multisig output (only if \"script\" is \"multisig\")\n"
|
||||
" \"pubkey\" : \"publickeyhex\", (string, optional) The hex value of the raw public key, for single-key addresses (possibly embedded in P2SH or P2WSH)\n"
|
||||
" \"embedded\" : {...}, (object, optional) information about the address embedded in P2SH or P2WSH, if relevant and known. It includes all validateaddress output fields for the embedded address, excluding \"isvalid\", metadata (\"timestamp\", \"hdkeypath\", \"hdmasterkeyid\") and relation to the wallet (\"ismine\", \"iswatchonly\", \"account\").\n"
|
||||
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
|
||||
" \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
|
||||
" \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
|
||||
" \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n"
|
||||
" \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
|
||||
" \"isscript\" : true|false, (boolean) If the key is a script\n"
|
||||
" \"iswitness\" : true|false, (boolean) If the address is a witness address\n"
|
||||
" \"witness_version\" : version (numeric, optional) The version number of the witness program\n"
|
||||
" \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
|
||||
+ HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
|
||||
);
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
|
||||
LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
|
||||
#else
|
||||
LOCK(cs_main);
|
||||
#endif
|
||||
|
||||
CTxDestination dest = DecodeDestination(request.params[0].get_str());
|
||||
bool isValid = IsValidDestination(dest);
|
||||
|
||||
|
@ -209,45 +67,22 @@ UniValue validateaddress(const JSONRPCRequest& request)
|
|||
ret.pushKV("isvalid", isValid);
|
||||
if (isValid)
|
||||
{
|
||||
std::string currentAddress = EncodeDestination(dest);
|
||||
ret.pushKV("address", currentAddress);
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO;
|
||||
ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE));
|
||||
ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY));
|
||||
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest);
|
||||
ret.pushKVs(detail);
|
||||
if (pwallet && pwallet->mapAddressBook.count(dest)) {
|
||||
ret.pushKV("account", pwallet->mapAddressBook[dest].name);
|
||||
}
|
||||
if (pwallet) {
|
||||
const CKeyMetadata* meta = nullptr;
|
||||
CKeyID key_id = GetKeyForDestination(*pwallet, dest);
|
||||
if (!key_id.IsNull()) {
|
||||
auto it = pwallet->mapKeyMetadata.find(key_id);
|
||||
if (it != pwallet->mapKeyMetadata.end()) {
|
||||
meta = &it->second;
|
||||
}
|
||||
}
|
||||
if (!meta) {
|
||||
auto it = pwallet->m_script_metadata.find(CScriptID(scriptPubKey));
|
||||
if (it != pwallet->m_script_metadata.end()) {
|
||||
meta = &it->second;
|
||||
}
|
||||
}
|
||||
if (meta) {
|
||||
ret.pushKV("timestamp", meta->nCreateTime);
|
||||
if (!meta->hdKeypath.empty()) {
|
||||
ret.pushKV("hdkeypath", meta->hdKeypath);
|
||||
ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex());
|
||||
}
|
||||
}
|
||||
if (!::vpwallets.empty() && IsDeprecatedRPCEnabled("validateaddress")) {
|
||||
ret.pushKVs(getaddressinfo(request));
|
||||
}
|
||||
#endif
|
||||
if (ret["address"].isNull()) {
|
||||
std::string currentAddress = EncodeDestination(dest);
|
||||
ret.pushKV("address", currentAddress);
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));;
|
||||
|
||||
UniValue detail = DescribeAddress(dest);
|
||||
ret.pushKVs(detail);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -66,3 +66,64 @@ CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
class DescribeAddressVisitor : public boost::static_visitor<UniValue>
|
||||
{
|
||||
public:
|
||||
explicit DescribeAddressVisitor() {}
|
||||
|
||||
UniValue operator()(const CNoDestination& dest) const
|
||||
{
|
||||
return UniValue(UniValue::VOBJ);
|
||||
}
|
||||
|
||||
UniValue operator()(const CKeyID& keyID) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("isscript", false);
|
||||
obj.pushKV("iswitness", false);
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const CScriptID& scriptID) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("isscript", true);
|
||||
obj.pushKV("iswitness", false);
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessV0KeyHash& id) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("isscript", false);
|
||||
obj.pushKV("iswitness", true);
|
||||
obj.pushKV("witness_version", 0);
|
||||
obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessV0ScriptHash& id) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("isscript", true);
|
||||
obj.pushKV("iswitness", true);
|
||||
obj.pushKV("witness_version", 0);
|
||||
obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessUnknown& id) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("iswitness", true);
|
||||
obj.pushKV("witness_version", (int)id.version);
|
||||
obj.pushKV("witness_program", HexStr(id.program, id.program + id.length));
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
UniValue DescribeAddress(const CTxDestination& dest)
|
||||
{
|
||||
return boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
#ifndef BITCOIN_RPC_UTIL_H
|
||||
#define BITCOIN_RPC_UTIL_H
|
||||
|
||||
#include <pubkey.h>
|
||||
#include <script/standard.h>
|
||||
#include <univalue.h>
|
||||
#include <utilstrencodings.h>
|
||||
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -16,4 +23,6 @@ CPubKey HexToPubKey(const std::string& hex_in);
|
|||
CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in);
|
||||
CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey>& pubkeys);
|
||||
|
||||
UniValue DescribeAddress(const CTxDestination& dest);
|
||||
|
||||
#endif // BITCOIN_RPC_UTIL_H
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <utilmoneystr.h>
|
||||
#include <wallet/coincontrol.h>
|
||||
#include <wallet/feebumper.h>
|
||||
#include <wallet/rpcwallet.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <wallet/walletdb.h>
|
||||
#include <wallet/walletutil.h>
|
||||
|
@ -3514,6 +3515,209 @@ UniValue rescanblockchain(const JSONRPCRequest& request)
|
|||
return response;
|
||||
}
|
||||
|
||||
class DescribeWalletAddressVisitor : public boost::static_visitor<UniValue>
|
||||
{
|
||||
public:
|
||||
CWallet * const pwallet;
|
||||
|
||||
void ProcessSubScript(const CScript& subscript, UniValue& obj, bool include_addresses = false) const
|
||||
{
|
||||
// Always present: script type and redeemscript
|
||||
txnouttype which_type;
|
||||
std::vector<std::vector<unsigned char>> solutions_data;
|
||||
Solver(subscript, which_type, solutions_data);
|
||||
obj.pushKV("script", GetTxnOutputType(which_type));
|
||||
obj.pushKV("hex", HexStr(subscript.begin(), subscript.end()));
|
||||
|
||||
CTxDestination embedded;
|
||||
UniValue a(UniValue::VARR);
|
||||
if (ExtractDestination(subscript, embedded)) {
|
||||
// Only when the script corresponds to an address.
|
||||
UniValue subobj(UniValue::VOBJ);
|
||||
UniValue detail = DescribeAddress(embedded);
|
||||
subobj.pushKVs(detail);
|
||||
UniValue wallet_detail = boost::apply_visitor(*this, embedded);
|
||||
subobj.pushKVs(wallet_detail);
|
||||
subobj.pushKV("address", EncodeDestination(embedded));
|
||||
subobj.pushKV("scriptPubKey", HexStr(subscript.begin(), subscript.end()));
|
||||
// Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works.
|
||||
if (subobj.exists("pubkey")) obj.pushKV("pubkey", subobj["pubkey"]);
|
||||
obj.pushKV("embedded", std::move(subobj));
|
||||
if (include_addresses) a.push_back(EncodeDestination(embedded));
|
||||
} else if (which_type == TX_MULTISIG) {
|
||||
// Also report some information on multisig scripts (which do not have a corresponding address).
|
||||
// TODO: abstract out the common functionality between this logic and ExtractDestinations.
|
||||
obj.pushKV("sigsrequired", solutions_data[0][0]);
|
||||
UniValue pubkeys(UniValue::VARR);
|
||||
for (size_t i = 1; i < solutions_data.size() - 1; ++i) {
|
||||
CPubKey key(solutions_data[i].begin(), solutions_data[i].end());
|
||||
if (include_addresses) a.push_back(EncodeDestination(key.GetID()));
|
||||
pubkeys.push_back(HexStr(key.begin(), key.end()));
|
||||
}
|
||||
obj.pushKV("pubkeys", std::move(pubkeys));
|
||||
}
|
||||
|
||||
// The "addresses" field is confusing because it refers to public keys using their P2PKH address.
|
||||
// For that reason, only add the 'addresses' field when needed for backward compatibility. New applications
|
||||
// can use the 'embedded'->'address' field for P2SH or P2WSH wrapped addresses, and 'pubkeys' for
|
||||
// inspecting multisig participants.
|
||||
if (include_addresses) obj.pushKV("addresses", std::move(a));
|
||||
}
|
||||
|
||||
explicit DescribeWalletAddressVisitor(CWallet* _pwallet) : pwallet(_pwallet) {}
|
||||
|
||||
UniValue operator()(const CNoDestination& dest) const { return UniValue(UniValue::VOBJ); }
|
||||
|
||||
UniValue operator()(const CKeyID& keyID) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CPubKey vchPubKey;
|
||||
if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) {
|
||||
obj.pushKV("pubkey", HexStr(vchPubKey));
|
||||
obj.pushKV("iscompressed", vchPubKey.IsCompressed());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const CScriptID& scriptID) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CScript subscript;
|
||||
if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
|
||||
ProcessSubScript(subscript, obj, IsDeprecatedRPCEnabled("validateaddress"));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessV0KeyHash& id) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CPubKey pubkey;
|
||||
if (pwallet && pwallet->GetPubKey(CKeyID(id), pubkey)) {
|
||||
obj.pushKV("pubkey", HexStr(pubkey));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessV0ScriptHash& id) const
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CScript subscript;
|
||||
CRIPEMD160 hasher;
|
||||
uint160 hash;
|
||||
hasher.Write(id.begin(), 32).Finalize(hash.begin());
|
||||
if (pwallet && pwallet->GetCScript(CScriptID(hash), subscript)) {
|
||||
ProcessSubScript(subscript, obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
UniValue operator()(const WitnessUnknown& id) const { return UniValue(UniValue::VOBJ); }
|
||||
};
|
||||
|
||||
UniValue DescribeWalletAddress(CWallet* pwallet, const CTxDestination& dest)
|
||||
{
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
UniValue detail = DescribeAddress(dest);
|
||||
ret.pushKVs(detail);
|
||||
ret.pushKVs(boost::apply_visitor(DescribeWalletAddressVisitor(pwallet), dest));
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue getaddressinfo(const JSONRPCRequest& request)
|
||||
{
|
||||
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
if (request.fHelp || request.params.size() != 1) {
|
||||
throw std::runtime_error(
|
||||
"getaddressinfo \"address\"\n"
|
||||
"\nReturn information about the given bitcoin address. Some information requires the address\n"
|
||||
"to be in the wallet.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"address\" (string, required) The bitcoin address to get the information of.\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"address\" : \"address\", (string) The bitcoin address validated\n"
|
||||
" \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
|
||||
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
|
||||
" \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
|
||||
" \"isscript\" : true|false, (boolean) If the key is a script\n"
|
||||
" \"iswitness\" : true|false, (boolean) If the address is a witness address\n"
|
||||
" \"witness_version\" : version (numeric, optional) The version number of the witness program\n"
|
||||
" \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program\n"
|
||||
" \"script\" : \"type\" (string, optional) The output script type. Only if \"isscript\" is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown\n"
|
||||
" \"hex\" : \"hex\", (string, optional) The redeemscript for the p2sh address\n"
|
||||
" \"pubkeys\" (string, optional) Array of pubkeys associated with the known redeemscript (only if \"script\" is \"multisig\")\n"
|
||||
" [\n"
|
||||
" \"pubkey\"\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
" \"sigsrequired\" : xxxxx (numeric, optional) Number of signatures required to spend multisig output (only if \"script\" is \"multisig\")\n"
|
||||
" \"pubkey\" : \"publickeyhex\", (string, optional) The hex value of the raw public key, for single-key addresses (possibly embedded in P2SH or P2WSH)\n"
|
||||
" \"embedded\" : {...}, (object, optional) Information about the address embedded in P2SH or P2WSH, if relevant and known. It includes all getaddressinfo output fields for the embedded address, excluding metadata (\"timestamp\", \"hdkeypath\", \"hdmasterkeyid\") and relation to the wallet (\"ismine\", \"iswatchonly\", \"account\").\n"
|
||||
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
|
||||
" \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
|
||||
" \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
|
||||
" \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n"
|
||||
" \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getaddressinfo", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
|
||||
+ HelpExampleRpc("getaddressinfo", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
|
||||
);
|
||||
}
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
CTxDestination dest = DecodeDestination(request.params[0].get_str());
|
||||
|
||||
// Make sure the destination is valid
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
|
||||
}
|
||||
|
||||
std::string currentAddress = EncodeDestination(dest);
|
||||
ret.pushKV("address", currentAddress);
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
|
||||
|
||||
isminetype mine = IsMine(*pwallet, dest);
|
||||
ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE));
|
||||
ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY));
|
||||
UniValue detail = DescribeWalletAddress(pwallet, dest);
|
||||
ret.pushKVs(detail);
|
||||
if (pwallet->mapAddressBook.count(dest)) {
|
||||
ret.pushKV("account", pwallet->mapAddressBook[dest].name);
|
||||
}
|
||||
const CKeyMetadata* meta = nullptr;
|
||||
CKeyID key_id = GetKeyForDestination(*pwallet, dest);
|
||||
if (!key_id.IsNull()) {
|
||||
auto it = pwallet->mapKeyMetadata.find(key_id);
|
||||
if (it != pwallet->mapKeyMetadata.end()) {
|
||||
meta = &it->second;
|
||||
}
|
||||
}
|
||||
if (!meta) {
|
||||
auto it = pwallet->m_script_metadata.find(CScriptID(scriptPubKey));
|
||||
if (it != pwallet->m_script_metadata.end()) {
|
||||
meta = &it->second;
|
||||
}
|
||||
}
|
||||
if (meta) {
|
||||
ret.pushKV("timestamp", meta->nCreateTime);
|
||||
if (!meta->hdKeypath.empty()) {
|
||||
ret.pushKV("hdkeypath", meta->hdKeypath);
|
||||
ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
|
||||
extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
|
||||
extern UniValue importprivkey(const JSONRPCRequest& request);
|
||||
|
@ -3543,6 +3747,7 @@ static const CRPCCommand commands[] =
|
|||
{ "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
|
||||
{ "wallet", "getaccount", &getaccount, {"address"} },
|
||||
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
|
||||
{ "wallet", "getaddressinfo", &getaddressinfo, {"address"} },
|
||||
{ "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
|
||||
{ "wallet", "getnewaddress", &getnewaddress, {"account","address_type"} },
|
||||
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} },
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
class CRPCTable;
|
||||
class CWallet;
|
||||
class JSONRPCRequest;
|
||||
class UniValue;
|
||||
|
||||
void RegisterWalletRPCCommands(CRPCTable &t);
|
||||
|
||||
|
@ -25,4 +26,6 @@ std::string HelpRequiringPassphrase(CWallet *);
|
|||
void EnsureWalletIsUnlocked(CWallet *);
|
||||
bool EnsureWalletIsAvailable(CWallet *, bool avoidException);
|
||||
|
||||
UniValue getaddressinfo(const JSONRPCRequest& request);
|
||||
|
||||
#endif //BITCOIN_WALLET_RPCWALLET_H
|
||||
|
|
|
@ -96,7 +96,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
wit_ids = [] # wit_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE via bare witness
|
||||
for i in range(3):
|
||||
newaddress = self.nodes[i].getnewaddress()
|
||||
self.pubkey.append(self.nodes[i].validateaddress(newaddress)["pubkey"])
|
||||
self.pubkey.append(self.nodes[i].getaddressinfo(newaddress)["pubkey"])
|
||||
multiscript = CScript([OP_1, hex_str_to_bytes(self.pubkey[-1]), OP_1, OP_CHECKMULTISIG])
|
||||
p2sh_addr = self.nodes[i].addwitnessaddress(newaddress)
|
||||
bip173_addr = self.nodes[i].addwitnessaddress(newaddress, False)
|
||||
|
@ -274,8 +274,8 @@ class SegWitTest(BitcoinTestFramework):
|
|||
uncompressed_spendable_address = ["mvozP4UwyGD2mGZU4D2eMvMLPB9WkMmMQu"]
|
||||
self.nodes[0].importprivkey("cNC8eQ5dg3mFAVePDX4ddmPYpPbw41r9bm2jd1nLJT77e6RrzTRR")
|
||||
compressed_spendable_address = ["mmWQubrDomqpgSYekvsU7HWEVjLFHAakLe"]
|
||||
assert ((self.nodes[0].validateaddress(uncompressed_spendable_address[0])['iscompressed'] == False))
|
||||
assert ((self.nodes[0].validateaddress(compressed_spendable_address[0])['iscompressed'] == True))
|
||||
assert ((self.nodes[0].getaddressinfo(uncompressed_spendable_address[0])['iscompressed'] == False))
|
||||
assert ((self.nodes[0].getaddressinfo(compressed_spendable_address[0])['iscompressed'] == True))
|
||||
|
||||
self.nodes[0].importpubkey(pubkeys[0])
|
||||
compressed_solvable_address = [key_to_p2pkh(pubkeys[0])]
|
||||
|
@ -308,7 +308,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
solvable_after_importaddress.append(CScript([OP_HASH160, hash160(script), OP_EQUAL]))
|
||||
|
||||
for i in compressed_spendable_address:
|
||||
v = self.nodes[0].validateaddress(i)
|
||||
v = self.nodes[0].getaddressinfo(i)
|
||||
if (v['isscript']):
|
||||
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
|
||||
# bare and p2sh multisig with compressed keys should always be spendable
|
||||
|
@ -325,7 +325,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
spendable_anytime.extend([p2wpkh, p2sh_p2wpkh])
|
||||
|
||||
for i in uncompressed_spendable_address:
|
||||
v = self.nodes[0].validateaddress(i)
|
||||
v = self.nodes[0].getaddressinfo(i)
|
||||
if (v['isscript']):
|
||||
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
|
||||
# bare and p2sh multisig with uncompressed keys should always be spendable
|
||||
|
@ -342,7 +342,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
unseen_anytime.extend([p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh])
|
||||
|
||||
for i in compressed_solvable_address:
|
||||
v = self.nodes[0].validateaddress(i)
|
||||
v = self.nodes[0].getaddressinfo(i)
|
||||
if (v['isscript']):
|
||||
# Multisig without private is not seen after addmultisigaddress, but seen after importaddress
|
||||
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
|
||||
|
@ -355,7 +355,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
solvable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh])
|
||||
|
||||
for i in uncompressed_solvable_address:
|
||||
v = self.nodes[0].validateaddress(i)
|
||||
v = self.nodes[0].getaddressinfo(i)
|
||||
if (v['isscript']):
|
||||
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
|
||||
# Base uncompressed multisig without private is not seen after addmultisigaddress, but seen after importaddress
|
||||
|
@ -395,7 +395,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
|
||||
importlist = []
|
||||
for i in compressed_spendable_address + uncompressed_spendable_address + compressed_solvable_address + uncompressed_solvable_address:
|
||||
v = self.nodes[0].validateaddress(i)
|
||||
v = self.nodes[0].getaddressinfo(i)
|
||||
if (v['isscript']):
|
||||
bare = hex_str_to_bytes(v['hex'])
|
||||
importlist.append(bytes_to_hex_str(bare))
|
||||
|
@ -473,7 +473,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
premature_witaddress = []
|
||||
|
||||
for i in compressed_spendable_address:
|
||||
v = self.nodes[0].validateaddress(i)
|
||||
v = self.nodes[0].getaddressinfo(i)
|
||||
if (v['isscript']):
|
||||
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
|
||||
# P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after addwitnessaddress
|
||||
|
@ -485,7 +485,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
spendable_anytime.extend([p2wpkh, p2sh_p2wpkh])
|
||||
|
||||
for i in uncompressed_spendable_address + uncompressed_solvable_address:
|
||||
v = self.nodes[0].validateaddress(i)
|
||||
v = self.nodes[0].getaddressinfo(i)
|
||||
if (v['isscript']):
|
||||
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
|
||||
# P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
|
||||
|
@ -496,7 +496,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
unseen_anytime.extend([p2wpkh, p2sh_p2wpkh])
|
||||
|
||||
for i in compressed_solvable_address:
|
||||
v = self.nodes[0].validateaddress(i)
|
||||
v = self.nodes[0].getaddressinfo(i)
|
||||
if (v['isscript']):
|
||||
# P2WSH multisig without private key are seen after addwitnessaddress
|
||||
[bare, p2sh, p2wsh, p2sh_p2wsh] = self.p2sh_address_to_script(v)
|
||||
|
@ -519,7 +519,7 @@ class SegWitTest(BitcoinTestFramework):
|
|||
assert_raises_rpc_error(-4, "Public key or redeemscript not known to wallet, or the key is uncompressed", self.nodes[0].addwitnessaddress, i)
|
||||
|
||||
# after importaddress it should pass addwitnessaddress
|
||||
v = self.nodes[0].validateaddress(compressed_solvable_address[1])
|
||||
v = self.nodes[0].getaddressinfo(compressed_solvable_address[1])
|
||||
self.nodes[0].importaddress(v['hex'],"",False,True)
|
||||
for i in compressed_spendable_address + compressed_solvable_address + premature_witaddress:
|
||||
witaddress = self.nodes[0].addwitnessaddress(i)
|
||||
|
|
|
@ -9,7 +9,7 @@ class DeprecatedRpcTest(BitcoinTestFramework):
|
|||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
self.setup_clean_chain = True
|
||||
self.extra_args = [[], []]
|
||||
self.extra_args = [[], ["-deprecatedrpc=validateaddress"]]
|
||||
|
||||
def run_test(self):
|
||||
# This test should be used to verify correct behaviour of deprecated
|
||||
|
@ -18,10 +18,13 @@ class DeprecatedRpcTest(BitcoinTestFramework):
|
|||
# self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses")
|
||||
# assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()])
|
||||
# self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
|
||||
#
|
||||
# There are currently no deprecated RPC methods in master, so this
|
||||
# test is currently empty.
|
||||
pass
|
||||
|
||||
self.log.info("Test validateaddress deprecation")
|
||||
SOME_ADDRESS = "mnvGjUy3NMj67yJ6gkK5o9e5RS33Z2Vqcu" # This is just some random address to pass as a parameter to validateaddress
|
||||
dep_validate_address = self.nodes[0].validateaddress(SOME_ADDRESS)
|
||||
assert "ismine" not in dep_validate_address
|
||||
not_dep_val = self.nodes[1].validateaddress(SOME_ADDRESS)
|
||||
assert "ismine" in not_dep_val
|
||||
|
||||
if __name__ == '__main__':
|
||||
DeprecatedRpcTest().main()
|
||||
|
|
|
@ -53,7 +53,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
assert_equal(rawmatch["changepos"], -1)
|
||||
|
||||
watchonly_address = self.nodes[0].getnewaddress()
|
||||
watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"]
|
||||
watchonly_pubkey = self.nodes[0].getaddressinfo(watchonly_address)["pubkey"]
|
||||
watchonly_amount = Decimal(200)
|
||||
self.nodes[3].importpubkey(watchonly_pubkey, "", True)
|
||||
watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
|
||||
|
@ -371,8 +371,8 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
addr1 = self.nodes[1].getnewaddress()
|
||||
addr2 = self.nodes[1].getnewaddress()
|
||||
|
||||
addr1Obj = self.nodes[1].validateaddress(addr1)
|
||||
addr2Obj = self.nodes[1].validateaddress(addr2)
|
||||
addr1Obj = self.nodes[1].getaddressinfo(addr1)
|
||||
addr2Obj = self.nodes[1].getaddressinfo(addr2)
|
||||
|
||||
mSigObj = self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
|
||||
|
||||
|
@ -401,11 +401,11 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
addr4 = self.nodes[1].getnewaddress()
|
||||
addr5 = self.nodes[1].getnewaddress()
|
||||
|
||||
addr1Obj = self.nodes[1].validateaddress(addr1)
|
||||
addr2Obj = self.nodes[1].validateaddress(addr2)
|
||||
addr3Obj = self.nodes[1].validateaddress(addr3)
|
||||
addr4Obj = self.nodes[1].validateaddress(addr4)
|
||||
addr5Obj = self.nodes[1].validateaddress(addr5)
|
||||
addr1Obj = self.nodes[1].getaddressinfo(addr1)
|
||||
addr2Obj = self.nodes[1].getaddressinfo(addr2)
|
||||
addr3Obj = self.nodes[1].getaddressinfo(addr3)
|
||||
addr4Obj = self.nodes[1].getaddressinfo(addr4)
|
||||
addr5Obj = self.nodes[1].getaddressinfo(addr5)
|
||||
|
||||
mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']])['address']
|
||||
|
||||
|
@ -431,8 +431,8 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
addr1 = self.nodes[2].getnewaddress()
|
||||
addr2 = self.nodes[2].getnewaddress()
|
||||
|
||||
addr1Obj = self.nodes[2].validateaddress(addr1)
|
||||
addr2Obj = self.nodes[2].validateaddress(addr2)
|
||||
addr1Obj = self.nodes[2].getaddressinfo(addr1)
|
||||
addr2Obj = self.nodes[2].getaddressinfo(addr2)
|
||||
|
||||
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ class ListTransactionsTest(BitcoinTestFramework):
|
|||
{"category":"receive","amount":Decimal("0.44")},
|
||||
{"txid":txid, "account" : "toself"} )
|
||||
|
||||
pubkey = self.nodes[1].validateaddress(self.nodes[1].getnewaddress())['pubkey']
|
||||
pubkey = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['pubkey']
|
||||
multisig = self.nodes[1].createmultisig(1, [pubkey])
|
||||
self.nodes[0].importaddress(multisig["redeemScript"], "watchonly", False, True)
|
||||
txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1)
|
||||
|
|
|
@ -146,8 +146,8 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
addr1 = self.nodes[2].getnewaddress()
|
||||
addr2 = self.nodes[2].getnewaddress()
|
||||
|
||||
addr1Obj = self.nodes[2].validateaddress(addr1)
|
||||
addr2Obj = self.nodes[2].validateaddress(addr2)
|
||||
addr1Obj = self.nodes[2].getaddressinfo(addr1)
|
||||
addr2Obj = self.nodes[2].getaddressinfo(addr2)
|
||||
|
||||
# Tests for createmultisig and addmultisigaddress
|
||||
assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, ["01020304"])
|
||||
|
@ -173,9 +173,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
addr2 = self.nodes[2].getnewaddress()
|
||||
addr3 = self.nodes[2].getnewaddress()
|
||||
|
||||
addr1Obj = self.nodes[1].validateaddress(addr1)
|
||||
addr2Obj = self.nodes[2].validateaddress(addr2)
|
||||
addr3Obj = self.nodes[2].validateaddress(addr3)
|
||||
addr1Obj = self.nodes[1].getaddressinfo(addr1)
|
||||
addr2Obj = self.nodes[2].getaddressinfo(addr2)
|
||||
addr3Obj = self.nodes[2].getaddressinfo(addr3)
|
||||
|
||||
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])['address']
|
||||
|
||||
|
@ -219,12 +219,12 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
addr1 = self.nodes[1].getnewaddress()
|
||||
addr2 = self.nodes[2].getnewaddress()
|
||||
|
||||
addr1Obj = self.nodes[1].validateaddress(addr1)
|
||||
addr2Obj = self.nodes[2].validateaddress(addr2)
|
||||
addr1Obj = self.nodes[1].getaddressinfo(addr1)
|
||||
addr2Obj = self.nodes[2].getaddressinfo(addr2)
|
||||
|
||||
self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
|
||||
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
|
||||
mSigObjValid = self.nodes[2].validateaddress(mSigObj)
|
||||
mSigObjValid = self.nodes[2].getaddressinfo(mSigObj)
|
||||
|
||||
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
|
||||
decTx = self.nodes[0].gettransaction(txId)
|
||||
|
|
|
@ -149,7 +149,7 @@ def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount):
|
|||
else:
|
||||
addr = key_to_p2sh_p2wpkh(pubkey) if encode_p2sh else key_to_p2wpkh(pubkey)
|
||||
if not encode_p2sh:
|
||||
assert_equal(node.validateaddress(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey))
|
||||
assert_equal(node.getaddressinfo(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey))
|
||||
return node.createrawtransaction([utxo], {addr: amount})
|
||||
|
||||
# Create a transaction spending a given utxo to a segwit output corresponding
|
||||
|
|
|
@ -93,8 +93,8 @@ class AddressTypeTest(BitcoinTestFramework):
|
|||
|
||||
def test_address(self, node, address, multisig, typ):
|
||||
"""Run sanity checks on an address."""
|
||||
info = self.nodes[node].validateaddress(address)
|
||||
assert(info['isvalid'])
|
||||
info = self.nodes[node].getaddressinfo(address)
|
||||
assert(self.nodes[node].validateaddress(address)['isvalid'])
|
||||
if not multisig and typ == 'legacy':
|
||||
# P2PKH
|
||||
assert(not info['isscript'])
|
||||
|
|
|
@ -66,7 +66,7 @@ class WalletTest(BitcoinTestFramework):
|
|||
assert_equal(txout['value'], 50)
|
||||
txout = self.nodes[0].gettxout(txid=confirmed_txid, n=confirmed_index, include_mempool=True)
|
||||
assert_equal(txout['value'], 50)
|
||||
|
||||
|
||||
# Send 21 BTC from 0 to 2 using sendtoaddress call.
|
||||
# Locked memory should use at least 32 bytes to sign each transaction
|
||||
self.log.info("test getmemoryinfo")
|
||||
|
@ -317,7 +317,7 @@ class WalletTest(BitcoinTestFramework):
|
|||
self.nodes[1].importaddress(address_to_import)
|
||||
|
||||
# 3. Validate that the imported address is watch-only on node1
|
||||
assert(self.nodes[1].validateaddress(address_to_import)["iswatchonly"])
|
||||
assert(self.nodes[1].getaddressinfo(address_to_import)["iswatchonly"])
|
||||
|
||||
# 4. Check that the unspents after import are not spendable
|
||||
assert_array_result(self.nodes[1].listunspent(),
|
||||
|
@ -442,5 +442,14 @@ class WalletTest(BitcoinTestFramework):
|
|||
# Verify nothing new in wallet
|
||||
assert_equal(total_txs, len(self.nodes[0].listtransactions("*",99999)))
|
||||
|
||||
# Test getaddressinfo. Note that these addresses are taken from disablewallet.py
|
||||
assert_raises_rpc_error(-5, "Invalid address", self.nodes[0].getaddressinfo, "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy")
|
||||
address_info = self.nodes[0].getaddressinfo("mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ")
|
||||
assert_equal(address_info['address'], "mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ")
|
||||
assert_equal(address_info["scriptPubKey"], "76a9144e3854046c7bd1594ac904e4793b6a45b36dea0988ac")
|
||||
assert not address_info["ismine"]
|
||||
assert not address_info["iswatchonly"]
|
||||
assert not address_info["isscript"]
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletTest().main()
|
||||
|
|
|
@ -104,7 +104,7 @@ def test_segwit_bumpfee_succeeds(rbf_node, dest_address):
|
|||
# which spends it, and make sure bumpfee can be called on it.
|
||||
|
||||
segwit_in = next(u for u in rbf_node.listunspent() if u["amount"] == Decimal("0.001"))
|
||||
segwit_out = rbf_node.validateaddress(rbf_node.getnewaddress())
|
||||
segwit_out = rbf_node.getaddressinfo(rbf_node.getnewaddress())
|
||||
rbf_node.addwitnessaddress(segwit_out["address"])
|
||||
segwitid = send_to_witness(
|
||||
use_p2wsh=False,
|
||||
|
|
|
@ -97,7 +97,7 @@ class WalletDumpTest(BitcoinTestFramework):
|
|||
addrs = []
|
||||
for i in range(0,test_addr_count):
|
||||
addr = self.nodes[0].getnewaddress()
|
||||
vaddr= self.nodes[0].validateaddress(addr) #required to get hd keypath
|
||||
vaddr= self.nodes[0].getaddressinfo(addr) #required to get hd keypath
|
||||
addrs.append(vaddr)
|
||||
# Should be a no-op:
|
||||
self.nodes[0].keypoolrefill()
|
||||
|
@ -143,13 +143,13 @@ class WalletDumpTest(BitcoinTestFramework):
|
|||
self.start_node(0, ['-wallet=w2'])
|
||||
|
||||
# Make sure the address is not IsMine before import
|
||||
result = self.nodes[0].validateaddress(multisig_addr)
|
||||
result = self.nodes[0].getaddressinfo(multisig_addr)
|
||||
assert(result['ismine'] == False)
|
||||
|
||||
self.nodes[0].importwallet(os.path.abspath(tmpdir + "/node0/wallet.unencrypted.dump"))
|
||||
|
||||
# Now check IsMine is true
|
||||
result = self.nodes[0].validateaddress(multisig_addr)
|
||||
result = self.nodes[0].getaddressinfo(multisig_addr)
|
||||
assert(result['ismine'] == True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -33,7 +33,7 @@ class WalletHDTest(BitcoinTestFramework):
|
|||
|
||||
# create an internal key
|
||||
change_addr = self.nodes[1].getrawchangeaddress()
|
||||
change_addrV= self.nodes[1].validateaddress(change_addr)
|
||||
change_addrV= self.nodes[1].getaddressinfo(change_addr)
|
||||
assert_equal(change_addrV["hdkeypath"], "m/0'/1'/0'") #first internal child key
|
||||
|
||||
# Import a non-HD private key in the HD wallet
|
||||
|
@ -51,7 +51,7 @@ class WalletHDTest(BitcoinTestFramework):
|
|||
num_hd_adds = 300
|
||||
for i in range(num_hd_adds):
|
||||
hd_add = self.nodes[1].getnewaddress()
|
||||
hd_info = self.nodes[1].validateaddress(hd_add)
|
||||
hd_info = self.nodes[1].getaddressinfo(hd_add)
|
||||
assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i)+"'")
|
||||
assert_equal(hd_info["hdmasterkeyid"], masterkeyid)
|
||||
self.nodes[0].sendtoaddress(hd_add, 1)
|
||||
|
@ -61,7 +61,7 @@ class WalletHDTest(BitcoinTestFramework):
|
|||
|
||||
# create an internal key (again)
|
||||
change_addr = self.nodes[1].getrawchangeaddress()
|
||||
change_addrV= self.nodes[1].validateaddress(change_addr)
|
||||
change_addrV= self.nodes[1].getaddressinfo(change_addr)
|
||||
assert_equal(change_addrV["hdkeypath"], "m/0'/1'/1'") #second internal child key
|
||||
|
||||
self.sync_all()
|
||||
|
@ -80,7 +80,7 @@ class WalletHDTest(BitcoinTestFramework):
|
|||
hd_add_2 = None
|
||||
for _ in range(num_hd_adds):
|
||||
hd_add_2 = self.nodes[1].getnewaddress()
|
||||
hd_info_2 = self.nodes[1].validateaddress(hd_add_2)
|
||||
hd_info_2 = self.nodes[1].getaddressinfo(hd_add_2)
|
||||
assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_)+"'")
|
||||
assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid)
|
||||
assert_equal(hd_add, hd_add_2)
|
||||
|
@ -114,7 +114,7 @@ class WalletHDTest(BitcoinTestFramework):
|
|||
keypath = ""
|
||||
for out in outs:
|
||||
if out['value'] != 1:
|
||||
keypath = self.nodes[1].validateaddress(out['scriptPubKey']['addresses'][0])['hdkeypath']
|
||||
keypath = self.nodes[1].getaddressinfo(out['scriptPubKey']['addresses'][0])['hdkeypath']
|
||||
|
||||
assert_equal(keypath[0:7], "m/0'/1'")
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ class ImportRescanTest(BitcoinTestFramework):
|
|||
# each possible type of wallet import RPC.
|
||||
for i, variant in enumerate(IMPORT_VARIANTS):
|
||||
variant.label = "label {} {}".format(i, variant)
|
||||
variant.address = self.nodes[1].validateaddress(self.nodes[1].getnewaddress(variant.label))
|
||||
variant.address = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress(variant.label))
|
||||
variant.key = self.nodes[1].dumpprivkey(variant.address["address"])
|
||||
variant.initial_amount = 10 - (i + 1) / 4.0
|
||||
variant.initial_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.initial_amount)
|
||||
|
|
|
@ -21,7 +21,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
self.nodes[1].generate(1)
|
||||
timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
|
||||
|
||||
node0_address1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
node0_address1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
|
||||
#Check only one address
|
||||
assert_equal(node0_address1['ismine'], True)
|
||||
|
@ -30,7 +30,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(self.nodes[1].getblockcount(),1)
|
||||
|
||||
#Address Test - before import
|
||||
address_info = self.nodes[1].validateaddress(node0_address1['address'])
|
||||
address_info = self.nodes[1].getaddressinfo(node0_address1['address'])
|
||||
assert_equal(address_info['iswatchonly'], False)
|
||||
assert_equal(address_info['ismine'], False)
|
||||
|
||||
|
@ -39,7 +39,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# Bitcoin Address
|
||||
self.log.info("Should import an address")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": {
|
||||
"address": address['address']
|
||||
|
@ -47,7 +47,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
"timestamp": "now",
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], True)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
@ -67,21 +67,21 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# ScriptPubKey + internal
|
||||
self.log.info("Should import a scriptPubKey with internal flag")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"timestamp": "now",
|
||||
"internal": True
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], True)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
||||
# ScriptPubKey + !internal
|
||||
self.log.info("Should not import a scriptPubKey without internal flag")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"timestamp": "now",
|
||||
|
@ -89,7 +89,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -8)
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal('timestamp' in address_assert, False)
|
||||
|
@ -97,7 +97,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# Address + Public key + !Internal
|
||||
self.log.info("Should import an address with public key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": {
|
||||
"address": address['address']
|
||||
|
@ -106,7 +106,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
"pubkeys": [ address['pubkey'] ]
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], True)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
@ -114,7 +114,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# ScriptPubKey + Public key + internal
|
||||
self.log.info("Should import a scriptPubKey with internal and with public key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
request = [{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"timestamp": "now",
|
||||
|
@ -123,14 +123,14 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
}]
|
||||
result = self.nodes[1].importmulti(request)
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], True)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
||||
# ScriptPubKey + Public key + !internal
|
||||
self.log.info("Should not import a scriptPubKey without internal and with public key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
request = [{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"timestamp": "now",
|
||||
|
@ -140,14 +140,14 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -8)
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal('timestamp' in address_assert, False)
|
||||
|
||||
# Address + Private key + !watchonly
|
||||
self.log.info("Should import an address with private key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": {
|
||||
"address": address['address']
|
||||
|
@ -156,7 +156,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
"keys": [ self.nodes[0].dumpprivkey(address['address']) ]
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], True)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
@ -175,7 +175,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# Address + Private key + watchonly
|
||||
self.log.info("Should not import an address with private key and with watchonly")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": {
|
||||
"address": address['address']
|
||||
|
@ -187,14 +187,14 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -8)
|
||||
assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal('timestamp' in address_assert, False)
|
||||
|
||||
# ScriptPubKey + Private key + internal
|
||||
self.log.info("Should import a scriptPubKey with internal and with private key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"timestamp": "now",
|
||||
|
@ -202,14 +202,14 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
"internal": True
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], True)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
||||
# ScriptPubKey + Private key + !internal
|
||||
self.log.info("Should not import a scriptPubKey without internal and with private key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"timestamp": "now",
|
||||
|
@ -218,16 +218,16 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -8)
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal('timestamp' in address_assert, False)
|
||||
|
||||
|
||||
# P2SH address
|
||||
sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
|
||||
self.nodes[1].generate(100)
|
||||
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
|
||||
|
@ -242,7 +242,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
"timestamp": "now",
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
|
||||
assert_equal(address_assert['isscript'], True)
|
||||
assert_equal(address_assert['iswatchonly'], True)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
@ -252,9 +252,9 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
|
||||
# P2SH + Redeem script
|
||||
sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
|
||||
self.nodes[1].generate(100)
|
||||
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
|
||||
|
@ -270,7 +270,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
"redeemscript": multi_sig_script['redeemScript']
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
||||
p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
|
||||
|
@ -279,9 +279,9 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
|
||||
# P2SH + Redeem script + Private Keys + !Watchonly
|
||||
sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
|
||||
self.nodes[1].generate(100)
|
||||
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
|
||||
|
@ -298,7 +298,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
"keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])]
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
||||
p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
|
||||
|
@ -306,9 +306,9 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(p2shunspent['solvable'], True)
|
||||
|
||||
# P2SH + Redeem script + Private Keys + Watchonly
|
||||
sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
|
||||
self.nodes[1].generate(100)
|
||||
transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
|
||||
|
@ -332,8 +332,8 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# Address + Public key + !Internal + Wrong pubkey
|
||||
self.log.info("Should not import an address with a wrong public key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": {
|
||||
"address": address['address']
|
||||
|
@ -344,7 +344,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -5)
|
||||
assert_equal(result[0]['error']['message'], 'Consistency check failed')
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal('timestamp' in address_assert, False)
|
||||
|
@ -352,8 +352,8 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# ScriptPubKey + Public key + internal + Wrong pubkey
|
||||
self.log.info("Should not import a scriptPubKey with internal and with a wrong public key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
request = [{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"timestamp": "now",
|
||||
|
@ -364,7 +364,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -5)
|
||||
assert_equal(result[0]['error']['message'], 'Consistency check failed')
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal('timestamp' in address_assert, False)
|
||||
|
@ -372,8 +372,8 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# Address + Private key + !watchonly + Wrong private key
|
||||
self.log.info("Should not import an address with a wrong private key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": {
|
||||
"address": address['address']
|
||||
|
@ -384,7 +384,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -5)
|
||||
assert_equal(result[0]['error']['message'], 'Consistency check failed')
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal('timestamp' in address_assert, False)
|
||||
|
@ -392,8 +392,8 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
|
||||
# ScriptPubKey + Private key + internal + Wrong private key
|
||||
self.log.info("Should not import a scriptPubKey with internal and with a wrong private key")
|
||||
address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"timestamp": "now",
|
||||
|
@ -403,7 +403,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -5)
|
||||
assert_equal(result[0]['error']['message'], 'Consistency check failed')
|
||||
address_assert = self.nodes[1].validateaddress(address['address'])
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal('timestamp' in address_assert, False)
|
||||
|
@ -419,7 +419,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
"timestamp": "now",
|
||||
}])
|
||||
assert_equal(result[0]['success'], True)
|
||||
address_assert = self.nodes[1].validateaddress(watchonly_address)
|
||||
address_assert = self.nodes[1].getaddressinfo(watchonly_address)
|
||||
assert_equal(address_assert['iswatchonly'], True)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
@ -429,7 +429,7 @@ class ImportMultiTest (BitcoinTestFramework):
|
|||
# restart nodes to check for proper serialization/deserialization of watch only address
|
||||
self.stop_nodes()
|
||||
self.start_nodes()
|
||||
address_assert = self.nodes[1].validateaddress(watchonly_address)
|
||||
address_assert = self.nodes[1].getaddressinfo(watchonly_address)
|
||||
assert_equal(address_assert['iswatchonly'], True)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal(address_assert['timestamp'], watchonly_timestamp)
|
||||
|
|
|
@ -26,7 +26,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
|
|||
address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey
|
||||
|
||||
#Check only one address
|
||||
address_info = self.nodes[0].validateaddress(address1)
|
||||
address_info = self.nodes[0].getaddressinfo(address1)
|
||||
assert_equal(address_info['ismine'], True)
|
||||
|
||||
self.sync_all()
|
||||
|
@ -35,15 +35,15 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
|
|||
assert_equal(self.nodes[1].getblockcount(),101)
|
||||
|
||||
#Address Test - before import
|
||||
address_info = self.nodes[1].validateaddress(address1)
|
||||
address_info = self.nodes[1].getaddressinfo(address1)
|
||||
assert_equal(address_info['iswatchonly'], False)
|
||||
assert_equal(address_info['ismine'], False)
|
||||
|
||||
address_info = self.nodes[1].validateaddress(address2)
|
||||
address_info = self.nodes[1].getaddressinfo(address2)
|
||||
assert_equal(address_info['iswatchonly'], False)
|
||||
assert_equal(address_info['ismine'], False)
|
||||
|
||||
address_info = self.nodes[1].validateaddress(address3)
|
||||
address_info = self.nodes[1].getaddressinfo(address3)
|
||||
assert_equal(address_info['iswatchonly'], False)
|
||||
assert_equal(address_info['ismine'], False)
|
||||
|
||||
|
@ -86,13 +86,13 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
|
|||
assert_equal(balance3, Decimal('0.075'))
|
||||
|
||||
#Addresses Test - after import
|
||||
address_info = self.nodes[1].validateaddress(address1)
|
||||
address_info = self.nodes[1].getaddressinfo(address1)
|
||||
assert_equal(address_info['iswatchonly'], False)
|
||||
assert_equal(address_info['ismine'], False)
|
||||
address_info = self.nodes[1].validateaddress(address2)
|
||||
address_info = self.nodes[1].getaddressinfo(address2)
|
||||
assert_equal(address_info['iswatchonly'], True)
|
||||
assert_equal(address_info['ismine'], False)
|
||||
address_info = self.nodes[1].validateaddress(address3)
|
||||
address_info = self.nodes[1].getaddressinfo(address3)
|
||||
assert_equal(address_info['iswatchonly'], False)
|
||||
assert_equal(address_info['ismine'], True)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class KeyPoolTest(BitcoinTestFramework):
|
|||
def run_test(self):
|
||||
nodes = self.nodes
|
||||
addr_before_encrypting = nodes[0].getnewaddress()
|
||||
addr_before_encrypting_data = nodes[0].validateaddress(addr_before_encrypting)
|
||||
addr_before_encrypting_data = nodes[0].getaddressinfo(addr_before_encrypting)
|
||||
wallet_info_old = nodes[0].getwalletinfo()
|
||||
assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['hdmasterkeyid'])
|
||||
|
||||
|
@ -24,7 +24,7 @@ class KeyPoolTest(BitcoinTestFramework):
|
|||
self.start_node(0)
|
||||
# Keep creating keys
|
||||
addr = nodes[0].getnewaddress()
|
||||
addr_data = nodes[0].validateaddress(addr)
|
||||
addr_data = nodes[0].getaddressinfo(addr)
|
||||
wallet_info = nodes[0].getwalletinfo()
|
||||
assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid'])
|
||||
assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid'])
|
||||
|
|
|
@ -68,7 +68,7 @@ class KeypoolRestoreTest(BitcoinTestFramework):
|
|||
assert_equal(self.nodes[1].listtransactions()[0]['category'], "receive")
|
||||
|
||||
# Check that we have marked all keys up to the used keypool key as used
|
||||
assert_equal(self.nodes[1].validateaddress(self.nodes[1].getnewaddress())['hdkeypath'], "m/0'/0'/110'")
|
||||
assert_equal(self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['hdkeypath'], "m/0'/0'/110'")
|
||||
|
||||
if __name__ == '__main__':
|
||||
KeypoolRestoreTest().main()
|
||||
|
|
Loading…
Reference in a new issue