Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/misc.cpp
| Show First 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | #endif | ||||
| obj.push_back(Pair("errors", GetWarnings("statusbar"))); | obj.push_back(Pair("errors", GetWarnings("statusbar"))); | ||||
| return obj; | return obj; | ||||
| } | } | ||||
| #ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
| class DescribeAddressVisitor : public boost::static_visitor<UniValue> { | class DescribeAddressVisitor : public boost::static_visitor<UniValue> { | ||||
| public: | public: | ||||
| CWallet *const pwallet; | CWallet *const pwallet; | ||||
| const Config &config; | |||||
deadalnix: If you add the config to the wallet, this is redundant. | |||||
matiuAuthorUnsubmitted Not Done Inline ActionsI seems to me that wallet shouldn't be the provider of 'config' to other classes. If we modify wallet in the future we could break classes that depend on that. Even more, don't you think 'config' on wallet should be private? matiu: I seems to me that wallet shouldn't be the provider of 'config' to other classes. If we modify… | |||||
| DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {} | DescribeAddressVisitor(CWallet *_pwallet, const Config &_config) | ||||
| : pwallet(_pwallet), config(_config) {} | |||||
| 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; | ||||
| Show All 14 Lines | UniValue operator()(const CScriptID &scriptID) const { | ||||
| txnouttype whichType; | txnouttype whichType; | ||||
| int nRequired; | int nRequired; | ||||
| ExtractDestinations(subscript, whichType, addresses, nRequired); | ExtractDestinations(subscript, whichType, addresses, nRequired); | ||||
| obj.push_back(Pair("script", GetTxnOutputType(whichType))); | obj.push_back(Pair("script", GetTxnOutputType(whichType))); | ||||
| obj.push_back( | obj.push_back( | ||||
| Pair("hex", HexStr(subscript.begin(), subscript.end()))); | Pair("hex", HexStr(subscript.begin(), subscript.end()))); | ||||
| UniValue a(UniValue::VARR); | UniValue a(UniValue::VARR); | ||||
| for (const CTxDestination &addr : addresses) { | for (const CTxDestination &addr : addresses) { | ||||
| a.push_back(EncodeDestination(addr)); | a.push_back(EncodeDestination(addr, config)); | ||||
| } | } | ||||
| obj.push_back(Pair("addresses", a)); | obj.push_back(Pair("addresses", a)); | ||||
| if (whichType == TX_MULTISIG) { | if (whichType == TX_MULTISIG) { | ||||
| obj.push_back(Pair("sigsrequired", nRequired)); | obj.push_back(Pair("sigsrequired", nRequired)); | ||||
| } | } | ||||
| } | } | ||||
| return obj; | return obj; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | #ifdef ENABLE_WALLET | ||||
| CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | ||||
| LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr); | LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr); | ||||
| #else | #else | ||||
| LOCK(cs_main); | LOCK(cs_main); | ||||
| #endif | #endif | ||||
| CTxDestination dest = | CTxDestination dest = | ||||
| DecodeDestination(request.params[0].get_str(), config.GetChainParams()); | DecodeDestination(request.params[0].get_str(), config); | ||||
| bool isValid = IsValidDestination(dest); | bool isValid = IsValidDestination(dest); | ||||
| UniValue ret(UniValue::VOBJ); | UniValue ret(UniValue::VOBJ); | ||||
| ret.push_back(Pair("isvalid", isValid)); | ret.push_back(Pair("isvalid", isValid)); | ||||
| if (isValid) { | if (isValid) { | ||||
| std::string currentAddress = EncodeDestination(dest); | std::string currentAddress = EncodeDestination(dest, config); | ||||
| ret.push_back(Pair("address", currentAddress)); | ret.push_back(Pair("address", currentAddress)); | ||||
| CScript scriptPubKey = GetScriptForDestination(dest); | CScript scriptPubKey = GetScriptForDestination(dest); | ||||
| ret.push_back(Pair("scriptPubKey", | ret.push_back(Pair("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.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); | ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); | ||||
| ret.push_back( | ret.push_back( | ||||
| Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true : false)); | Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true : false)); | ||||
| UniValue detail = | UniValue detail = | ||||
| boost::apply_visitor(DescribeAddressVisitor(pwallet), dest); | boost::apply_visitor(DescribeAddressVisitor(pwallet, config), dest); | ||||
| ret.pushKVs(detail); | ret.pushKVs(detail); | ||||
| if (pwallet && pwallet->mapAddressBook.count(dest)) { | if (pwallet && pwallet->mapAddressBook.count(dest)) { | ||||
| ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name)); | ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name)); | ||||
| } | } | ||||
| if (pwallet) { | if (pwallet) { | ||||
| const auto &meta = pwallet->mapKeyMetadata; | const auto &meta = pwallet->mapKeyMetadata; | ||||
| const CKeyID *keyID = boost::get<CKeyID>(&dest); | const CKeyID *keyID = boost::get<CKeyID>(&dest); | ||||
| auto it = keyID ? meta.find(*keyID) : meta.end(); | auto it = keyID ? meta.find(*keyID) : meta.end(); | ||||
| Show All 15 Lines | |||||
| } | } | ||||
| // Needed even with !ENABLE_WALLET, to pass (ignored) pointers around | // Needed even with !ENABLE_WALLET, to pass (ignored) pointers around | ||||
| class CWallet; | class CWallet; | ||||
| /** | /** | ||||
| * Used by addmultisigaddress / createmultisig: | * Used by addmultisigaddress / createmultisig: | ||||
| */ | */ | ||||
| CScript createmultisig_redeemScript(CWallet *const pwallet, | CScript createmultisig_redeemScript(const Config &config, | ||||
deadalnixUnsubmitted Not Done Inline ActionsRedundant. deadalnix: Redundant. | |||||
| CWallet *const pwallet, | |||||
| const UniValue ¶ms) { | const UniValue ¶ms) { | ||||
| int nRequired = params[0].get_int(); | int nRequired = params[0].get_int(); | ||||
| const UniValue &keys = params[1].get_array(); | const UniValue &keys = params[1].get_array(); | ||||
| // Gather public keys | // Gather public keys | ||||
| if (nRequired < 1) { | if (nRequired < 1) { | ||||
| throw std::runtime_error( | throw std::runtime_error( | ||||
| "a multisignature address must require at least one key to redeem"); | "a multisignature address must require at least one key to redeem"); | ||||
| Show All 12 Lines | CScript createmultisig_redeemScript(const Config &config, | ||||
| } | } | ||||
| std::vector<CPubKey> pubkeys; | std::vector<CPubKey> pubkeys; | ||||
| pubkeys.resize(keys.size()); | pubkeys.resize(keys.size()); | ||||
| for (size_t i = 0; i < keys.size(); i++) { | for (size_t i = 0; i < keys.size(); i++) { | ||||
| const std::string &ks = keys[i].get_str(); | const std::string &ks = keys[i].get_str(); | ||||
| #ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
| // Case 1: Bitcoin address and we have full public key: | // Case 1: Bitcoin address and we have full public key: | ||||
| if (pwallet) { | if (pwallet) { | ||||
| CTxDestination dest = DecodeDestination(ks, pwallet->chainParams); | CTxDestination dest = DecodeDestination(ks, config); | ||||
| if (IsValidDestination(dest)) { | if (IsValidDestination(dest)) { | ||||
| const CKeyID *keyID = boost::get<CKeyID>(&dest); | const CKeyID *keyID = boost::get<CKeyID>(&dest); | ||||
| if (!keyID) { | if (!keyID) { | ||||
| throw std::runtime_error( | throw std::runtime_error( | ||||
| strprintf("%s does not refer to a key", ks)); | strprintf("%s does not refer to a key", ks)); | ||||
| } | } | ||||
| CPubKey vchPubKey; | CPubKey vchPubKey; | ||||
| if (!pwallet->GetPubKey(*keyID, vchPubKey)) { | if (!pwallet->GetPubKey(*keyID, vchPubKey)) { | ||||
| ▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() < 2 || | ||||
| HelpExampleRpc("createmultisig", | HelpExampleRpc("createmultisig", | ||||
| "2, " | "2, " | ||||
| "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\"," | "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\"," | ||||
| "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\""); | "\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\""); | ||||
| throw std::runtime_error(msg); | throw std::runtime_error(msg); | ||||
| } | } | ||||
| // Construct using pay-to-script-hash: | // Construct using pay-to-script-hash: | ||||
| CScript inner = createmultisig_redeemScript(pwallet, request.params); | CScript inner = | ||||
| createmultisig_redeemScript(config, pwallet, request.params); | |||||
| CScriptID innerID(inner); | CScriptID innerID(inner); | ||||
| UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
| result.push_back(Pair("address", EncodeDestination(innerID))); | result.push_back(Pair("address", EncodeDestination(innerID, config))); | ||||
| result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); | result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); | ||||
| return result; | return result; | ||||
| } | } | ||||
| static UniValue verifymessage(const Config &config, | static UniValue verifymessage(const Config &config, | ||||
| const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
| if (request.fHelp || request.params.size() != 3) { | if (request.fHelp || request.params.size() != 3) { | ||||
| Show All 27 Lines | static UniValue verifymessage(const Config &config, | ||||
| } | } | ||||
| LOCK(cs_main); | LOCK(cs_main); | ||||
| std::string strAddress = request.params[0].get_str(); | std::string strAddress = request.params[0].get_str(); | ||||
| std::string strSign = request.params[1].get_str(); | std::string strSign = request.params[1].get_str(); | ||||
| std::string strMessage = request.params[2].get_str(); | std::string strMessage = request.params[2].get_str(); | ||||
| CTxDestination destination = | CTxDestination destination = DecodeDestination(strAddress, config); | ||||
| DecodeDestination(strAddress, config.GetChainParams()); | |||||
| if (!IsValidDestination(destination)) { | if (!IsValidDestination(destination)) { | ||||
| throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); | throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); | ||||
| } | } | ||||
| const CKeyID *keyID = boost::get<CKeyID>(&destination); | const CKeyID *keyID = boost::get<CKeyID>(&destination); | ||||
| if (!keyID) { | if (!keyID) { | ||||
| throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); | throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 188 Lines • Show Last 20 Lines | |||||
If you add the config to the wallet, this is redundant.