1 // Copyright (c) 2017-2019 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <key_io.h>
6 #include <keystore.h>
7 #include <policy/fees.h>
8 #include <outputtype.h>
9 #include <rpc/util.h>
10 #include <tinyformat.h>
11 #include <util/strencodings.h>
12 #include <validation.h>
13
14 InitInterfaces* g_rpc_interfaces = nullptr;
15
16 // Converts a hex string to a public key if possible
HexToPubKey(const std::string & hex_in)17 CPubKey HexToPubKey(const std::string& hex_in)
18 {
19 if (!IsHex(hex_in)) {
20 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid public key: " + hex_in);
21 }
22 CPubKey vchPubKey(ParseHex(hex_in));
23 if (!vchPubKey.IsFullyValid()) {
24 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid public key: " + hex_in);
25 }
26 return vchPubKey;
27 }
28
29 // Retrieves a public key for an address from the given CKeyStore
AddrToPubKey(CKeyStore * const keystore,const std::string & addr_in)30 CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in)
31 {
32 CTxDestination dest = DecodeDestination(addr_in);
33 if (!IsValidDestination(dest)) {
34 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address: " + addr_in);
35 }
36 CKeyID key = GetKeyForDestination(*keystore, dest);
37 if (key.IsNull()) {
38 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("%s does not refer to a key", addr_in));
39 }
40 CPubKey vchPubKey;
41 if (!keystore->GetPubKey(key, vchPubKey)) {
42 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("no full public key for address %s", addr_in));
43 }
44 if (!vchPubKey.IsFullyValid()) {
45 throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet contains an invalid public key");
46 }
47 return vchPubKey;
48 }
49
50 // Creates a multisig address from a given list of public keys, number of signatures required, and the address type
AddAndGetMultisigDestination(const int required,const std::vector<CPubKey> & pubkeys,OutputType type,CKeyStore & keystore,CScript & script_out)51 CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, CKeyStore& keystore, CScript& script_out)
52 {
53 // Gather public keys
54 if (required < 1) {
55 throw JSONRPCError(RPC_INVALID_PARAMETER, "a multisignature address must require at least one key to redeem");
56 }
57 if ((int)pubkeys.size() < required) {
58 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("not enough keys supplied (got %u keys, but need at least %d to redeem)", pubkeys.size(), required));
59 }
60 if (pubkeys.size() > 16) {
61 throw JSONRPCError(RPC_INVALID_PARAMETER, "Number of keys involved in the multisignature address creation > 16\nReduce the number");
62 }
63
64 script_out = GetScriptForMultisig(required, pubkeys);
65
66 if (script_out.size() > MAX_SCRIPT_ELEMENT_SIZE) {
67 throw JSONRPCError(RPC_INVALID_PARAMETER, (strprintf("redeemScript exceeds size limit: %d > %d", script_out.size(), MAX_SCRIPT_ELEMENT_SIZE)));
68 }
69
70 // Check if any keys are uncompressed. If so, the type is legacy
71 for (const CPubKey& pk : pubkeys) {
72 if (!pk.IsCompressed()) {
73 type = OutputType::LEGACY;
74 break;
75 }
76 }
77
78 // Make the address
79 CTxDestination dest = AddAndGetDestinationForScript(keystore, script_out, type);
80
81 return dest;
82 }
83
84 class DescribeAddressVisitor : public boost::static_visitor<UniValue>
85 {
86 public:
DescribeAddressVisitor()87 explicit DescribeAddressVisitor() {}
88
operator ()(const CNoDestination & dest) const89 UniValue operator()(const CNoDestination& dest) const
90 {
91 return UniValue(UniValue::VOBJ);
92 }
93
operator ()(const CKeyID & keyID) const94 UniValue operator()(const CKeyID& keyID) const
95 {
96 UniValue obj(UniValue::VOBJ);
97 obj.pushKV("isscript", false);
98 obj.pushKV("iswitness", false);
99 return obj;
100 }
101
operator ()(const CScriptID & scriptID) const102 UniValue operator()(const CScriptID& scriptID) const
103 {
104 UniValue obj(UniValue::VOBJ);
105 obj.pushKV("isscript", true);
106 obj.pushKV("iswitness", false);
107 return obj;
108 }
109
operator ()(const WitnessV0KeyHash & id) const110 UniValue operator()(const WitnessV0KeyHash& id) const
111 {
112 UniValue obj(UniValue::VOBJ);
113 obj.pushKV("isscript", false);
114 obj.pushKV("iswitness", true);
115 obj.pushKV("witness_version", 0);
116 obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
117 return obj;
118 }
119
operator ()(const WitnessV0ScriptHash & id) const120 UniValue operator()(const WitnessV0ScriptHash& id) const
121 {
122 UniValue obj(UniValue::VOBJ);
123 obj.pushKV("isscript", true);
124 obj.pushKV("iswitness", true);
125 obj.pushKV("witness_version", 0);
126 obj.pushKV("witness_program", HexStr(id.begin(), id.end()));
127 return obj;
128 }
129
operator ()(const WitnessUnknown & id) const130 UniValue operator()(const WitnessUnknown& id) const
131 {
132 UniValue obj(UniValue::VOBJ);
133 obj.pushKV("iswitness", true);
134 obj.pushKV("witness_version", (int)id.version);
135 obj.pushKV("witness_program", HexStr(id.program, id.program + id.length));
136 return obj;
137 }
138 };
139
DescribeAddress(const CTxDestination & dest)140 UniValue DescribeAddress(const CTxDestination& dest)
141 {
142 return boost::apply_visitor(DescribeAddressVisitor(), dest);
143 }
144
ParseConfirmTarget(const UniValue & value)145 unsigned int ParseConfirmTarget(const UniValue& value)
146 {
147 int target = value.get_int();
148 unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
149 if (target < 1 || (unsigned int)target > max_target) {
150 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid conf_target, must be between %u - %u", 1, max_target));
151 }
152 return (unsigned int)target;
153 }
154
RPCErrorFromTransactionError(TransactionError terr)155 RPCErrorCode RPCErrorFromTransactionError(TransactionError terr)
156 {
157 switch (terr) {
158 case TransactionError::MEMPOOL_REJECTED:
159 return RPC_TRANSACTION_REJECTED;
160 case TransactionError::ALREADY_IN_CHAIN:
161 return RPC_TRANSACTION_ALREADY_IN_CHAIN;
162 case TransactionError::P2P_DISABLED:
163 return RPC_CLIENT_P2P_DISABLED;
164 case TransactionError::INVALID_PSBT:
165 case TransactionError::PSBT_MISMATCH:
166 return RPC_INVALID_PARAMETER;
167 case TransactionError::SIGHASH_MISMATCH:
168 return RPC_DESERIALIZATION_ERROR;
169 default: break;
170 }
171 return RPC_TRANSACTION_ERROR;
172 }
173
JSONRPCTransactionError(TransactionError terr,const std::string & err_string)174 UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string)
175 {
176 if (err_string.length() > 0) {
177 return JSONRPCError(RPCErrorFromTransactionError(terr), err_string);
178 } else {
179 return JSONRPCError(RPCErrorFromTransactionError(terr), TransactionErrorString(terr));
180 }
181 }
182
183 struct Section {
SectionSection184 Section(const std::string& left, const std::string& right)
185 : m_left{left}, m_right{right} {}
186 const std::string m_left;
187 const std::string m_right;
188 };
189
190 struct Sections {
191 std::vector<Section> m_sections;
192 size_t m_max_pad{0};
193
PushSectionSections194 void PushSection(const Section& s)
195 {
196 m_max_pad = std::max(m_max_pad, s.m_left.size());
197 m_sections.push_back(s);
198 }
199
200 enum class OuterType {
201 ARR,
202 OBJ,
203 NAMED_ARG, // Only set on first recursion
204 };
205
PushSections206 void Push(const RPCArg& arg, const size_t current_indent = 5, const OuterType outer_type = OuterType::NAMED_ARG)
207 {
208 const auto indent = std::string(current_indent, ' ');
209 const auto indent_next = std::string(current_indent + 2, ' ');
210 switch (arg.m_type) {
211 case RPCArg::Type::STR_HEX:
212 case RPCArg::Type::STR:
213 case RPCArg::Type::NUM:
214 case RPCArg::Type::AMOUNT:
215 case RPCArg::Type::RANGE:
216 case RPCArg::Type::BOOL: {
217 if (outer_type == OuterType::NAMED_ARG) return; // Nothing more to do for non-recursive types on first recursion
218 auto left = indent;
219 if (arg.m_type_str.size() != 0 && outer_type == OuterType::OBJ) {
220 left += "\"" + arg.m_name + "\": " + arg.m_type_str.at(0);
221 } else {
222 left += outer_type == OuterType::OBJ ? arg.ToStringObj(/* oneline */ false) : arg.ToString(/* oneline */ false);
223 }
224 left += ",";
225 PushSection({left, arg.ToDescriptionString()});
226 break;
227 }
228 case RPCArg::Type::OBJ:
229 case RPCArg::Type::OBJ_USER_KEYS: {
230 const auto right = outer_type == OuterType::NAMED_ARG ? "" : arg.ToDescriptionString();
231 PushSection({indent + "{", right});
232 for (const auto& arg_inner : arg.m_inner) {
233 Push(arg_inner, current_indent + 2, OuterType::OBJ);
234 }
235 if (arg.m_type != RPCArg::Type::OBJ) {
236 PushSection({indent_next + "...", ""});
237 }
238 PushSection({indent + "}" + (outer_type != OuterType::NAMED_ARG ? "," : ""), ""});
239 break;
240 }
241 case RPCArg::Type::ARR: {
242 auto left = indent;
243 left += outer_type == OuterType::OBJ ? "\"" + arg.m_name + "\": " : "";
244 left += "[";
245 const auto right = outer_type == OuterType::NAMED_ARG ? "" : arg.ToDescriptionString();
246 PushSection({left, right});
247 for (const auto& arg_inner : arg.m_inner) {
248 Push(arg_inner, current_indent + 2, OuterType::ARR);
249 }
250 PushSection({indent_next + "...", ""});
251 PushSection({indent + "]" + (outer_type != OuterType::NAMED_ARG ? "," : ""), ""});
252 break;
253 }
254
255 // no default case, so the compiler can warn about missing cases
256 }
257 }
258
ToStringSections259 std::string ToString() const
260 {
261 std::string ret;
262 const size_t pad = m_max_pad + 4;
263 for (const auto& s : m_sections) {
264 if (s.m_right.empty()) {
265 ret += s.m_left;
266 ret += "\n";
267 continue;
268 }
269
270 std::string left = s.m_left;
271 left.resize(pad, ' ');
272 ret += left;
273
274 // Properly pad after newlines
275 std::string right;
276 size_t begin = 0;
277 size_t new_line_pos = s.m_right.find_first_of('\n');
278 while (true) {
279 right += s.m_right.substr(begin, new_line_pos - begin);
280 if (new_line_pos == std::string::npos) {
281 break; //No new line
282 }
283 right += "\n" + std::string(pad, ' ');
284 begin = s.m_right.find_first_not_of(' ', new_line_pos + 1);
285 if (begin == std::string::npos) {
286 break; // Empty line
287 }
288 new_line_pos = s.m_right.find_first_of('\n', begin + 1);
289 }
290 ret += right;
291 ret += "\n";
292 }
293 return ret;
294 }
295 };
296
RPCHelpMan(std::string name,std::string description,std::vector<RPCArg> args,RPCResults results,RPCExamples examples)297 RPCHelpMan::RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples)
298 : m_name{std::move(name)},
299 m_description{std::move(description)},
300 m_args{std::move(args)},
301 m_results{std::move(results)},
302 m_examples{std::move(examples)}
303 {
304 std::set<std::string> named_args;
305 for (const auto& arg : m_args) {
306 // Should have unique named arguments
307 assert(named_args.insert(arg.m_name).second);
308 }
309 }
310
ToDescriptionString() const311 std::string RPCResults::ToDescriptionString() const
312 {
313 std::string result;
314 for (const auto& r : m_results) {
315 if (r.m_cond.empty()) {
316 result += "\nResult:\n";
317 } else {
318 result += "\nResult (" + r.m_cond + "):\n";
319 }
320 result += r.m_result;
321 }
322 return result;
323 }
324
ToDescriptionString() const325 std::string RPCExamples::ToDescriptionString() const
326 {
327 return m_examples.empty() ? m_examples : "\nExamples:\n" + m_examples;
328 }
329
IsValidNumArgs(size_t num_args) const330 bool RPCHelpMan::IsValidNumArgs(size_t num_args) const
331 {
332 size_t num_required_args = 0;
333 for (size_t n = m_args.size(); n > 0; --n) {
334 if (!m_args.at(n - 1).IsOptional()) {
335 num_required_args = n;
336 break;
337 }
338 }
339 return num_required_args <= num_args && num_args <= m_args.size();
340 }
ToString() const341 std::string RPCHelpMan::ToString() const
342 {
343 std::string ret;
344
345 // Oneline summary
346 ret += m_name;
347 bool was_optional{false};
348 for (const auto& arg : m_args) {
349 const bool optional = arg.IsOptional();
350 ret += " ";
351 if (optional) {
352 if (!was_optional) ret += "( ";
353 was_optional = true;
354 } else {
355 if (was_optional) ret += ") ";
356 was_optional = false;
357 }
358 ret += arg.ToString(/* oneline */ true);
359 }
360 if (was_optional) ret += " )";
361 ret += "\n";
362
363 // Description
364 ret += m_description;
365
366 // Arguments
367 Sections sections;
368 for (size_t i{0}; i < m_args.size(); ++i) {
369 const auto& arg = m_args.at(i);
370
371 if (i == 0) ret += "\nArguments:\n";
372
373 // Push named argument name and description
374 sections.m_sections.emplace_back(std::to_string(i + 1) + ". " + arg.m_name, arg.ToDescriptionString());
375 sections.m_max_pad = std::max(sections.m_max_pad, sections.m_sections.back().m_left.size());
376
377 // Recursively push nested args
378 sections.Push(arg);
379 }
380 ret += sections.ToString();
381
382 // Result
383 ret += m_results.ToDescriptionString();
384
385 // Examples
386 ret += m_examples.ToDescriptionString();
387
388 return ret;
389 }
390
IsOptional() const391 bool RPCArg::IsOptional() const
392 {
393 if (m_fallback.which() == 1) {
394 return true;
395 } else {
396 return RPCArg::Optional::NO != boost::get<RPCArg::Optional>(m_fallback);
397 }
398 }
399
ToDescriptionString() const400 std::string RPCArg::ToDescriptionString() const
401 {
402 std::string ret;
403 ret += "(";
404 if (m_type_str.size() != 0) {
405 ret += m_type_str.at(1);
406 } else {
407 switch (m_type) {
408 case Type::STR_HEX:
409 case Type::STR: {
410 ret += "string";
411 break;
412 }
413 case Type::NUM: {
414 ret += "numeric";
415 break;
416 }
417 case Type::AMOUNT: {
418 ret += "numeric or string";
419 break;
420 }
421 case Type::RANGE: {
422 ret += "numeric or array";
423 break;
424 }
425 case Type::BOOL: {
426 ret += "boolean";
427 break;
428 }
429 case Type::OBJ:
430 case Type::OBJ_USER_KEYS: {
431 ret += "json object";
432 break;
433 }
434 case Type::ARR: {
435 ret += "json array";
436 break;
437 }
438
439 // no default case, so the compiler can warn about missing cases
440 }
441 }
442 if (m_fallback.which() == 1) {
443 ret += ", optional, default=" + boost::get<std::string>(m_fallback);
444 } else {
445 switch (boost::get<RPCArg::Optional>(m_fallback)) {
446 case RPCArg::Optional::OMITTED: {
447 // nothing to do. Element is treated as if not present and has no default value
448 break;
449 }
450 case RPCArg::Optional::OMITTED_NAMED_ARG: {
451 ret += ", optional"; // Default value is "null"
452 break;
453 }
454 case RPCArg::Optional::NO: {
455 ret += ", required";
456 break;
457 }
458
459 // no default case, so the compiler can warn about missing cases
460 }
461 }
462 ret += ")";
463 ret += m_description.empty() ? "" : " " + m_description;
464 return ret;
465 }
466
ToStringObj(const bool oneline) const467 std::string RPCArg::ToStringObj(const bool oneline) const
468 {
469 std::string res;
470 res += "\"";
471 res += m_name;
472 if (oneline) {
473 res += "\":";
474 } else {
475 res += "\": ";
476 }
477 switch (m_type) {
478 case Type::STR:
479 return res + "\"str\"";
480 case Type::STR_HEX:
481 return res + "\"hex\"";
482 case Type::NUM:
483 return res + "n";
484 case Type::RANGE:
485 return res + "n or [n,n]";
486 case Type::AMOUNT:
487 return res + "amount";
488 case Type::BOOL:
489 return res + "bool";
490 case Type::ARR:
491 res += "[";
492 for (const auto& i : m_inner) {
493 res += i.ToString(oneline) + ",";
494 }
495 return res + "...]";
496 case Type::OBJ:
497 case Type::OBJ_USER_KEYS:
498 // Currently unused, so avoid writing dead code
499 assert(false);
500
501 // no default case, so the compiler can warn about missing cases
502 }
503 assert(false);
504 }
505
ToString(const bool oneline) const506 std::string RPCArg::ToString(const bool oneline) const
507 {
508 if (oneline && !m_oneline_description.empty()) return m_oneline_description;
509
510 switch (m_type) {
511 case Type::STR_HEX:
512 case Type::STR: {
513 return "\"" + m_name + "\"";
514 }
515 case Type::NUM:
516 case Type::RANGE:
517 case Type::AMOUNT:
518 case Type::BOOL: {
519 return m_name;
520 }
521 case Type::OBJ:
522 case Type::OBJ_USER_KEYS: {
523 std::string res;
524 for (size_t i = 0; i < m_inner.size();) {
525 res += m_inner[i].ToStringObj(oneline);
526 if (++i < m_inner.size()) res += ",";
527 }
528 if (m_type == Type::OBJ) {
529 return "{" + res + "}";
530 } else {
531 return "{" + res + ",...}";
532 }
533 }
534 case Type::ARR: {
535 std::string res;
536 for (const auto& i : m_inner) {
537 res += i.ToString(oneline) + ",";
538 }
539 return "[" + res + "...]";
540 }
541
542 // no default case, so the compiler can warn about missing cases
543 }
544 assert(false);
545 }
546
ParseRange(const UniValue & value)547 std::pair<int64_t, int64_t> ParseRange(const UniValue& value)
548 {
549 if (value.isNum()) {
550 return {0, value.get_int64()};
551 }
552 if (value.isArray() && value.size() == 2 && value[0].isNum() && value[1].isNum()) {
553 int64_t low = value[0].get_int64();
554 int64_t high = value[1].get_int64();
555 if (low > high) throw JSONRPCError(RPC_INVALID_PARAMETER, "Range specified as [begin,end] must not have begin after end");
556 return {low, high};
557 }
558 throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified as end or as [begin,end]");
559 }
560