]> Git Repo - VerusCoin.git/blame - src/rpcmisc.cpp
test
[VerusCoin.git] / src / rpcmisc.cpp
CommitLineData
652e1569 1// Copyright (c) 2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
72fb3d29 3// Distributed under the MIT software license, see the accompanying
652e1569
WL
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "base58.h"
71697f97 7#include "clientversion.h"
652e1569
WL
8#include "init.h"
9#include "main.h"
10#include "net.h"
11#include "netbase.h"
c037531d 12#include "rpcserver.h"
14f888ca 13#include "timedata.h"
652e1569
WL
14#include "util.h"
15#ifdef ENABLE_WALLET
50c72f23
JS
16#include "wallet/wallet.h"
17#include "wallet/walletdb.h"
652e1569
WL
18#endif
19
20#include <stdint.h>
21
22#include <boost/assign/list_of.hpp>
23#include "json/json_spirit_utils.h"
24#include "json/json_spirit_value.h"
25
4e16a724
S
26#include "zcash/Address.hpp"
27
652e1569 28using namespace json_spirit;
40a158e1 29using namespace std;
652e1569 30
f9de17ec
WL
31/**
32 * @note Do not add or change anything in the information returned by this
72fb3d29 33 * method. `getinfo` exists for backwards-compatibility only. It combines
f9de17ec
WL
34 * information from wildly different sources in the program, which is a mess,
35 * and is thus planned to be deprecated eventually.
36 *
37 * Based on the source of the information, new information should be added to:
38 * - `getblockchaininfo`,
39 * - `getnetworkinfo` or
40 * - `getwalletinfo`
41 *
42 * Or alternatively, create a specific query method for the information.
43 **/
da16b12e 44uint64_t komodo_interestsum();
f595c2e0 45int32_t komodo_longestchain();
c75c18fc 46int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp);
58033467 47int32_t komodo_whoami(char *pubkeystr,int32_t height);
09e3cf94 48
16bc9aaf
WL
49Value getinfo(const Array& params, bool fHelp)
50{
c75c18fc 51 uint256 notarized_hash,notarized_desttxid;
a19b28ce 52 int32_t notarized_height,longestchain;
16bc9aaf
WL
53 if (fHelp || params.size() != 0)
54 throw runtime_error(
55 "getinfo\n"
56 "Returns an object containing various state info.\n"
57 "\nResult:\n"
58 "{\n"
59 " \"version\": xxxxx, (numeric) the server version\n"
60 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
61 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
62 " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
63 " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
64 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
65 " \"connections\": xxxxx, (numeric) the number of connections\n"
66 " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
67 " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
68 " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
69 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
70 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
16bc9aaf 71 " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
1294cdc4
GM
72 " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n"
73 " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
16bc9aaf
WL
74 " \"errors\": \"...\" (string) any error messages\n"
75 "}\n"
76 "\nExamples:\n"
77 + HelpExampleCli("getinfo", "")
78 + HelpExampleRpc("getinfo", "")
79 );
80
4401b2d7
EL
81#ifdef ENABLE_WALLET
82 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
83#else
84 LOCK(cs_main);
85#endif
86
16bc9aaf
WL
87 proxyType proxy;
88 GetProxy(NET_IPV4, proxy);
c75c18fc 89 notarized_height = komodo_notarized_height(&notarized_hash,&notarized_desttxid);
16bc9aaf
WL
90
91 Object obj;
faadbe17
PK
92 obj.push_back(Pair("version", CLIENT_VERSION));
93 obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
c75c18fc 94 obj.push_back(Pair("notarized", notarized_height));
95 obj.push_back(Pair("notarizedhash", notarized_hash.ToString()));
96 obj.push_back(Pair("notarizedtxid", notarized_desttxid.ToString()));
16bc9aaf
WL
97#ifdef ENABLE_WALLET
98 if (pwalletMain) {
99 obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
100 obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
da16b12e 101 obj.push_back(Pair("interest", ValueFromAmount(komodo_interestsum())));
16bc9aaf
WL
102 }
103#endif
104 obj.push_back(Pair("blocks", (int)chainActive.Height()));
a19b28ce 105 if ( (longestchain= komodo_longestchain()) != 0 && chainActive.Height() > longestchain )
106 longestchain = chainActive.Height();
107 obj.push_back(Pair("longestchain", longestchain));
d56e30ca 108 obj.push_back(Pair("timeoffset", GetTimeOffset()));
98d166cf 109 if ( chainActive.Tip() != 0 )
49c9db6a 110 obj.push_back(Pair("tiptime", (int)chainActive.Tip()->nTime));
16bc9aaf 111 obj.push_back(Pair("connections", (int)vNodes.size()));
67a79493 112 obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
16bc9aaf 113 obj.push_back(Pair("difficulty", (double)GetDifficulty()));
cc972107 114 obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
16bc9aaf
WL
115#ifdef ENABLE_WALLET
116 if (pwalletMain) {
d56e30ca 117 obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
16bc9aaf
WL
118 obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
119 }
16bc9aaf 120 if (pwalletMain && pwalletMain->IsCrypted())
d56e30ca 121 obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
c6cb21d1 122 obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
16bc9aaf 123#endif
13fc83c7 124 obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
16bc9aaf 125 obj.push_back(Pair("errors", GetWarnings("statusbar")));
58033467 126 {
127 char pubkeystr[65]; int32_t notaryid;
730a5006 128 notaryid = komodo_whoami(pubkeystr,longestchain);
129 obj.push_back(Pair("notaryid", notaryid));
130 obj.push_back(Pair("pubkey", pubkeystr));
58033467 131 }
16bc9aaf
WL
132 return obj;
133}
134
452955f5
WL
135#ifdef ENABLE_WALLET
136class DescribeAddressVisitor : public boost::static_visitor<Object>
137{
c8988460
PW
138private:
139 isminetype mine;
140
452955f5 141public:
c8988460
PW
142 DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {}
143
452955f5
WL
144 Object operator()(const CNoDestination &dest) const { return Object(); }
145
146 Object operator()(const CKeyID &keyID) const {
147 Object obj;
148 CPubKey vchPubKey;
452955f5 149 obj.push_back(Pair("isscript", false));
a3e192a3 150 if (mine == ISMINE_SPENDABLE) {
c8988460
PW
151 pwalletMain->GetPubKey(keyID, vchPubKey);
152 obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
153 obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
154 }
452955f5
WL
155 return obj;
156 }
157
158 Object operator()(const CScriptID &scriptID) const {
159 Object obj;
160 obj.push_back(Pair("isscript", true));
a3e192a3 161 if (mine != ISMINE_NO) {
c8988460
PW
162 CScript subscript;
163 pwalletMain->GetCScript(scriptID, subscript);
164 std::vector<CTxDestination> addresses;
165 txnouttype whichType;
166 int nRequired;
167 ExtractDestinations(subscript, whichType, addresses, nRequired);
168 obj.push_back(Pair("script", GetTxnOutputType(whichType)));
169 obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
170 Array a;
171 BOOST_FOREACH(const CTxDestination& addr, addresses)
172 a.push_back(CBitcoinAddress(addr).ToString());
173 obj.push_back(Pair("addresses", a));
174 if (whichType == TX_MULTISIG)
175 obj.push_back(Pair("sigsrequired", nRequired));
176 }
452955f5
WL
177 return obj;
178 }
179};
180#endif
181
182Value validateaddress(const Array& params, bool fHelp)
183{
184 if (fHelp || params.size() != 1)
185 throw runtime_error(
186 "validateaddress \"bitcoinaddress\"\n"
187 "\nReturn information about the given bitcoin address.\n"
188 "\nArguments:\n"
189 "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
190 "\nResult:\n"
191 "{\n"
192 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
193 " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
426a74ed 194 " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
452955f5
WL
195 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
196 " \"isscript\" : true|false, (boolean) If the key is a script\n"
197 " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
198 " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
7b782f5b 199 " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
452955f5
WL
200 "}\n"
201 "\nExamples:\n"
202 + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
203 + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
204 );
205
4401b2d7
EL
206#ifdef ENABLE_WALLET
207 LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
208#else
209 LOCK(cs_main);
210#endif
211
452955f5
WL
212 CBitcoinAddress address(params[0].get_str());
213 bool isValid = address.IsValid();
214
215 Object ret;
216 ret.push_back(Pair("isvalid", isValid));
217 if (isValid)
218 {
219 CTxDestination dest = address.Get();
220 string currentAddress = address.ToString();
221 ret.push_back(Pair("address", currentAddress));
426a74ed
PT
222
223 CScript scriptPubKey = GetScriptForDestination(dest);
224 ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
225
452955f5 226#ifdef ENABLE_WALLET
a3e192a3
J
227 isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
228 ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
229 if (mine != ISMINE_NO) {
230 ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
c8988460 231 Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
452955f5
WL
232 ret.insert(ret.end(), detail.begin(), detail.end());
233 }
234 if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
235 ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
236#endif
237 }
238 return ret;
239}
240
4e16a724
S
241
242Value z_validateaddress(const Array& params, bool fHelp)
243{
244 if (fHelp || params.size() != 1)
245 throw runtime_error(
246 "z_validateaddress \"zaddr\"\n"
247 "\nReturn information about the given z address.\n"
248 "\nArguments:\n"
249 "1. \"zaddr\" (string, required) The z address to validate\n"
250 "\nResult:\n"
251 "{\n"
252 " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
253 " \"address\" : \"zaddr\", (string) The z address validated\n"
254 " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
255 " \"payingkey\" : \"hex\", (string) The hex value of the paying key, a_pk\n"
256 " \"transmissionkey\" : \"hex\", (string) The hex value of the transmission key, pk_enc\n"
257
258 "}\n"
259 "\nExamples:\n"
260 + HelpExampleCli("validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"")
261 );
262
263
264#ifdef ENABLE_WALLET
265 LOCK2(cs_main, pwalletMain->cs_wallet);
266#else
267 LOCK(cs_main);
268#endif
269
270 bool isValid = false;
271 bool isMine = false;
272 std::string payingKey, transmissionKey;
273
274 string strAddress = params[0].get_str();
275 try {
276 CZCPaymentAddress address(strAddress);
277 libzcash::PaymentAddress addr = address.Get();
278
279#ifdef ENABLE_WALLET
280 isMine = pwalletMain->HaveSpendingKey(addr);
281#endif
282 payingKey = addr.a_pk.GetHex();
283 transmissionKey = addr.pk_enc.GetHex();
284 isValid = true;
285 } catch (std::runtime_error e) {
286 // address is invalid, nop here as isValid is false.
287 }
288
289 Object ret;
290 ret.push_back(Pair("isvalid", isValid));
291 if (isValid)
292 {
293 ret.push_back(Pair("address", strAddress));
294 ret.push_back(Pair("payingkey", payingKey));
295 ret.push_back(Pair("transmissionkey", transmissionKey));
296#ifdef ENABLE_WALLET
297 ret.push_back(Pair("ismine", isMine));
298#endif
299 }
300 return ret;
301}
302
303
72fb3d29
MF
304/**
305 * Used by addmultisigaddress / createmultisig:
306 */
787ee0c9 307CScript _createmultisig_redeemScript(const Array& params)
723a03d2
WL
308{
309 int nRequired = params[0].get_int();
310 const Array& keys = params[1].get_array();
311
312 // Gather public keys
313 if (nRequired < 1)
314 throw runtime_error("a multisignature address must require at least one key to redeem");
315 if ((int)keys.size() < nRequired)
316 throw runtime_error(
317 strprintf("not enough keys supplied "
783b182c 318 "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
e5d9d77d 319 if (keys.size() > 16)
320 throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
723a03d2
WL
321 std::vector<CPubKey> pubkeys;
322 pubkeys.resize(keys.size());
323 for (unsigned int i = 0; i < keys.size(); i++)
324 {
325 const std::string& ks = keys[i].get_str();
326#ifdef ENABLE_WALLET
327 // Case 1: Bitcoin address and we have full public key:
328 CBitcoinAddress address(ks);
329 if (pwalletMain && address.IsValid())
330 {
331 CKeyID keyID;
332 if (!address.GetKeyID(keyID))
333 throw runtime_error(
7d9d134b 334 strprintf("%s does not refer to a key",ks));
723a03d2
WL
335 CPubKey vchPubKey;
336 if (!pwalletMain->GetPubKey(keyID, vchPubKey))
337 throw runtime_error(
7d9d134b 338 strprintf("no full public key for address %s",ks));
723a03d2
WL
339 if (!vchPubKey.IsFullyValid())
340 throw runtime_error(" Invalid public key: "+ks);
341 pubkeys[i] = vchPubKey;
342 }
343
344 // Case 2: hex public key
345 else
346#endif
347 if (IsHex(ks))
348 {
349 CPubKey vchPubKey(ParseHex(ks));
350 if (!vchPubKey.IsFullyValid())
351 throw runtime_error(" Invalid public key: "+ks);
352 pubkeys[i] = vchPubKey;
353 }
354 else
355 {
356 throw runtime_error(" Invalid public key: "+ks);
357 }
358 }
0be990ba 359 CScript result = GetScriptForMultisig(nRequired, pubkeys);
787ee0c9
PT
360
361 if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
362 throw runtime_error(
363 strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
364
723a03d2
WL
365 return result;
366}
367
368Value createmultisig(const Array& params, bool fHelp)
369{
370 if (fHelp || params.size() < 2 || params.size() > 2)
371 {
372 string msg = "createmultisig nrequired [\"key\",...]\n"
373 "\nCreates a multi-signature address with n signature of m keys required.\n"
374 "It returns a json object with the address and redeemScript.\n"
375
376 "\nArguments:\n"
377 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
378 "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
379 " [\n"
380 " \"key\" (string) bitcoin address or hex-encoded public key\n"
381 " ,...\n"
382 " ]\n"
383
384 "\nResult:\n"
385 "{\n"
386 " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
387 " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
388 "}\n"
389
390 "\nExamples:\n"
391 "\nCreate a multisig address from 2 addresses\n"
392 + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
393 "\nAs a json rpc call\n"
e3e3728f 394 + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
723a03d2
WL
395 ;
396 throw runtime_error(msg);
397 }
398
399 // Construct using pay-to-script-hash:
787ee0c9 400 CScript inner = _createmultisig_redeemScript(params);
066e2a14 401 CScriptID innerID(inner);
723a03d2
WL
402 CBitcoinAddress address(innerID);
403
404 Object result;
405 result.push_back(Pair("address", address.ToString()));
406 result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
407
408 return result;
409}
410
c3a7f516
WL
411Value verifymessage(const Array& params, bool fHelp)
412{
413 if (fHelp || params.size() != 3)
414 throw runtime_error(
415 "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
416 "\nVerify a signed message\n"
417 "\nArguments:\n"
418 "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
419 "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
420 "3. \"message\" (string, required) The message that was signed.\n"
421 "\nResult:\n"
422 "true|false (boolean) If the signature is verified or not.\n"
423 "\nExamples:\n"
424 "\nUnlock the wallet for 30 seconds\n"
425 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
426 "\nCreate the signature\n"
427 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
428 "\nVerify the signature\n"
429 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
430 "\nAs json rpc\n"
431 + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
432 );
433
4401b2d7
EL
434 LOCK(cs_main);
435
c3a7f516
WL
436 string strAddress = params[0].get_str();
437 string strSign = params[1].get_str();
438 string strMessage = params[2].get_str();
439
440 CBitcoinAddress addr(strAddress);
441 if (!addr.IsValid())
442 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
443
444 CKeyID keyID;
445 if (!addr.GetKeyID(keyID))
446 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
447
448 bool fInvalid = false;
449 vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
450
451 if (fInvalid)
452 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
453
454 CHashWriter ss(SER_GETHASH, 0);
455 ss << strMessageMagic;
456 ss << strMessage;
457
458 CPubKey pubkey;
459 if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
460 return false;
461
462 return (pubkey.GetID() == keyID);
463}
a8b2ce55
GA
464
465Value setmocktime(const Array& params, bool fHelp)
466{
467 if (fHelp || params.size() != 1)
468 throw runtime_error(
469 "setmocktime timestamp\n"
470 "\nSet the local time to given timestamp (-regtest only)\n"
471 "\nArguments:\n"
472 "1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n"
473 " Pass 0 to go back to using the system time."
474 );
475
476 if (!Params().MineBlocksOnDemand())
477 throw runtime_error("setmocktime for regression testing (-regtest mode) only");
478
4401b2d7
EL
479 LOCK(cs_main);
480
a8b2ce55
GA
481 RPCTypeCheck(params, boost::assign::list_of(int_type));
482 SetMockTime(params[0].get_int64());
483
484 return Value::null;
485}
This page took 0.26051 seconds and 4 git commands to generate.