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