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