Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/misc.cpp
Show All 27 Lines | |||||
#include <univalue.h> | #include <univalue.h> | ||||
#include <cstdint> | #include <cstdint> | ||||
#ifdef HAVE_MALLOC_INFO | #ifdef HAVE_MALLOC_INFO | ||||
#include <malloc.h> | #include <malloc.h> | ||||
#endif | #endif | ||||
#ifdef ENABLE_WALLET | |||||
class DescribeAddressVisitor : public boost::static_visitor<UniValue> { | class DescribeAddressVisitor : public boost::static_visitor<UniValue> { | ||||
public: | public: | ||||
CWallet *const pwallet; | explicit DescribeAddressVisitor() {} | ||||
explicit DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} | UniValue operator()(const CNoDestination &dest) const { | ||||
return UniValue(UniValue::VOBJ); | |||||
} | |||||
UniValue operator()(const CKeyID &keyID) const { | |||||
UniValue obj(UniValue::VOBJ); | |||||
obj.pushKV("isscript", false); | |||||
return obj; | |||||
} | |||||
UniValue operator()(const CScriptID &scriptID) const { | |||||
UniValue obj(UniValue::VOBJ); | |||||
obj.pushKV("isscript", true); | |||||
return obj; | |||||
} | |||||
}; | |||||
#ifdef ENABLE_WALLET | |||||
class DescribeWalletAddressVisitor : public boost::static_visitor<UniValue> { | |||||
public: | |||||
CWallet *const pwallet; | |||||
void ProcessSubScript(const CScript &subscript, UniValue &obj, | void ProcessSubScript(const CScript &subscript, UniValue &obj, | ||||
bool include_addresses = false) const { | bool include_addresses = false) const { | ||||
// Always present: script type and redeemscript | // Always present: script type and redeemscript | ||||
txnouttype which_type; | txnouttype which_type; | ||||
std::vector<std::vector<uint8_t>> solutions_data; | std::vector<std::vector<uint8_t>> solutions_data; | ||||
Solver(subscript, which_type, solutions_data); | Solver(subscript, which_type, solutions_data); | ||||
obj.pushKV("script", GetTxnOutputType(which_type)); | obj.pushKV("script", GetTxnOutputType(which_type)); | ||||
obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); | obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); | ||||
CTxDestination embedded; | CTxDestination embedded; | ||||
UniValue a(UniValue::VARR); | UniValue a(UniValue::VARR); | ||||
if (ExtractDestination(subscript, embedded)) { | if (ExtractDestination(subscript, embedded)) { | ||||
// Only when the script corresponds to an address. | // Only when the script corresponds to an address. | ||||
UniValue subobj = boost::apply_visitor(*this, embedded); | UniValue subobj(UniValue::VOBJ); | ||||
UniValue detail = | |||||
boost::apply_visitor(DescribeAddressVisitor(), embedded); | |||||
subobj.pushKVs(detail); | |||||
UniValue wallet_detail = boost::apply_visitor(*this, embedded); | |||||
subobj.pushKVs(wallet_detail); | |||||
subobj.pushKV("address", EncodeDestination(embedded)); | subobj.pushKV("address", EncodeDestination(embedded)); | ||||
subobj.pushKV("scriptPubKey", | subobj.pushKV("scriptPubKey", | ||||
HexStr(subscript.begin(), subscript.end())); | HexStr(subscript.begin(), subscript.end())); | ||||
// Always report the pubkey at the top level, so that | // Always report the pubkey at the top level, so that | ||||
// `getnewaddress()['pubkey']` always works. | // `getnewaddress()['pubkey']` always works. | ||||
if (subobj.exists("pubkey")) { | if (subobj.exists("pubkey")) { | ||||
obj.pushKV("pubkey", subobj["pubkey"]); | obj.pushKV("pubkey", subobj["pubkey"]); | ||||
} | } | ||||
Show All 22 Lines | void ProcessSubScript(const CScript &subscript, UniValue &obj, | ||||
// using their P2PKH address. For that reason, only add the 'addresses' | // using their P2PKH address. For that reason, only add the 'addresses' | ||||
// field when needed for backward compatibility. New applications can | // field when needed for backward compatibility. New applications can | ||||
// use the 'pubkeys' field for inspecting multisig participants. | // use the 'pubkeys' field for inspecting multisig participants. | ||||
if (include_addresses) { | if (include_addresses) { | ||||
obj.pushKV("addresses", std::move(a)); | obj.pushKV("addresses", std::move(a)); | ||||
} | } | ||||
} | } | ||||
explicit DescribeWalletAddressVisitor(CWallet *_pwallet) | |||||
: pwallet(_pwallet) {} | |||||
UniValue operator()(const CNoDestination &dest) const { | UniValue operator()(const CNoDestination &dest) const { | ||||
return UniValue(UniValue::VOBJ); | return UniValue(UniValue::VOBJ); | ||||
} | } | ||||
UniValue operator()(const CKeyID &keyID) const { | UniValue operator()(const CKeyID &keyID) const { | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
CPubKey vchPubKey; | CPubKey vchPubKey; | ||||
obj.pushKV("isscript", false); | |||||
if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) { | if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) { | ||||
obj.pushKV("pubkey", HexStr(vchPubKey)); | obj.pushKV("pubkey", HexStr(vchPubKey)); | ||||
obj.pushKV("iscompressed", vchPubKey.IsCompressed()); | obj.pushKV("iscompressed", vchPubKey.IsCompressed()); | ||||
} | } | ||||
return obj; | return obj; | ||||
} | } | ||||
UniValue operator()(const CScriptID &scriptID) const { | UniValue operator()(const CScriptID &scriptID) const { | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
CScript subscript; | CScript subscript; | ||||
obj.pushKV("isscript", true); | |||||
if (pwallet && pwallet->GetCScript(scriptID, subscript)) { | if (pwallet && pwallet->GetCScript(scriptID, subscript)) { | ||||
ProcessSubScript(subscript, obj, true); | ProcessSubScript(subscript, obj, true); | ||||
} | } | ||||
return obj; | return obj; | ||||
} | } | ||||
}; | }; | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | if (isValid) { | ||||
CScript scriptPubKey = GetScriptForDestination(dest); | CScript scriptPubKey = GetScriptForDestination(dest); | ||||
ret.pushKV("scriptPubKey", | ret.pushKV("scriptPubKey", | ||||
HexStr(scriptPubKey.begin(), scriptPubKey.end())); | HexStr(scriptPubKey.begin(), scriptPubKey.end())); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO; | isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO; | ||||
ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE)); | ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE)); | ||||
ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); | ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); | ||||
UniValue detail = | UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest); | ||||
boost::apply_visitor(DescribeAddressVisitor(pwallet), dest); | |||||
ret.pushKVs(detail); | ret.pushKVs(detail); | ||||
UniValue wallet_detail = | |||||
boost::apply_visitor(DescribeWalletAddressVisitor(pwallet), dest); | |||||
ret.pushKVs(wallet_detail); | |||||
if (pwallet && pwallet->mapAddressBook.count(dest)) { | if (pwallet && pwallet->mapAddressBook.count(dest)) { | ||||
ret.pushKV("account", pwallet->mapAddressBook[dest].name); | ret.pushKV("account", pwallet->mapAddressBook[dest].name); | ||||
} | } | ||||
if (pwallet) { | if (pwallet) { | ||||
const CKeyMetadata *meta = nullptr; | const CKeyMetadata *meta = nullptr; | ||||
CKeyID key_id = GetKeyForDestination(*pwallet, dest); | CKeyID key_id = GetKeyForDestination(*pwallet, dest); | ||||
if (!key_id.IsNull()) { | if (!key_id.IsNull()) { | ||||
auto it = pwallet->mapKeyMetadata.find(key_id); | auto it = pwallet->mapKeyMetadata.find(key_id); | ||||
▲ Show 20 Lines • Show All 400 Lines • Show Last 20 Lines |