Logic running with -keypool=0 was wrong (empty keys were being returned). Fixes #445
[novacoin.git] / src / rpc.cpp
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2011 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "headers.h"
7 #include "cryptopp/sha.h"
8 #include "db.h"
9 #include "net.h"
10 #include "init.h"
11 #undef printf
12 #include <boost/asio.hpp>
13 #include <boost/iostreams/concepts.hpp>
14 #include <boost/iostreams/stream.hpp>
15 #include <boost/algorithm/string.hpp>
16 #ifdef USE_SSL
17 #include <boost/asio/ssl.hpp> 
18 #include <boost/filesystem.hpp>
19 #include <boost/filesystem/fstream.hpp>
20 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
21 #endif
22 #include "json/json_spirit_reader_template.h"
23 #include "json/json_spirit_writer_template.h"
24 #include "json/json_spirit_utils.h"
25 #define printf OutputDebugStringF
26 // MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
27 // precompiled in headers.h.  The problem might be when the pch file goes over
28 // a certain size around 145MB.  If we need access to json_spirit outside this
29 // file, we could use the compiled json_spirit option.
30
31 using namespace std;
32 using namespace boost;
33 using namespace boost::asio;
34 using namespace json_spirit;
35
36 void ThreadRPCServer2(void* parg);
37 typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
38 extern map<string, rpcfn_type> mapCallTable;
39
40 static int64 nWalletUnlockTime;
41 static CCriticalSection cs_nWalletUnlockTime;
42
43
44 Object JSONRPCError(int code, const string& message)
45 {
46     Object error;
47     error.push_back(Pair("code", code));
48     error.push_back(Pair("message", message));
49     return error;
50 }
51
52
53 void PrintConsole(const char* format, ...)
54 {
55     char buffer[50000];
56     int limit = sizeof(buffer);
57     va_list arg_ptr;
58     va_start(arg_ptr, format);
59     int ret = _vsnprintf(buffer, limit, format, arg_ptr);
60     va_end(arg_ptr);
61     if (ret < 0 || ret >= limit)
62     {
63         ret = limit - 1;
64         buffer[limit-1] = 0;
65     }
66     printf("%s", buffer);
67 #if defined(__WXMSW__) && defined(GUI)
68     MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION);
69 #else
70     fprintf(stdout, "%s", buffer);
71 #endif
72 }
73
74
75 int64 AmountFromValue(const Value& value)
76 {
77     double dAmount = value.get_real();
78     if (dAmount <= 0.0 || dAmount > 21000000.0)
79         throw JSONRPCError(-3, "Invalid amount");
80     int64 nAmount = roundint64(dAmount * COIN);
81     if (!MoneyRange(nAmount))
82         throw JSONRPCError(-3, "Invalid amount");
83     return nAmount;
84 }
85
86 Value ValueFromAmount(int64 amount)
87 {
88     return (double)amount / (double)COIN;
89 }
90
91 void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
92 {
93     entry.push_back(Pair("confirmations", wtx.GetDepthInMainChain()));
94     entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
95     entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
96     BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
97         entry.push_back(Pair(item.first, item.second));
98 }
99
100 string AccountFromValue(const Value& value)
101 {
102     string strAccount = value.get_str();
103     if (strAccount == "*")
104         throw JSONRPCError(-11, "Invalid account name");
105     return strAccount;
106 }
107
108
109
110 ///
111 /// Note: This interface may still be subject to change.
112 ///
113
114
115 Value help(const Array& params, bool fHelp)
116 {
117     if (fHelp || params.size() > 1)
118         throw runtime_error(
119             "help [command]\n"
120             "List commands, or get help for a command.");
121
122     string strCommand;
123     if (params.size() > 0)
124         strCommand = params[0].get_str();
125
126     string strRet;
127     set<rpcfn_type> setDone;
128     for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
129     {
130         string strMethod = (*mi).first;
131         // We already filter duplicates, but these deprecated screw up the sort order
132         if (strMethod == "getamountreceived" ||
133             strMethod == "getallreceived" ||
134             (strMethod.find("label") != string::npos))
135             continue;
136         if (strCommand != "" && strMethod != strCommand)
137             continue;
138         try
139         {
140             Array params;
141             rpcfn_type pfn = (*mi).second;
142             if (setDone.insert(pfn).second)
143                 (*pfn)(params, true);
144         }
145         catch (std::exception& e)
146         {
147             // Help text is returned in an exception
148             string strHelp = string(e.what());
149             if (strCommand == "")
150                 if (strHelp.find('\n') != -1)
151                     strHelp = strHelp.substr(0, strHelp.find('\n'));
152             strRet += strHelp + "\n";
153         }
154     }
155     if (strRet == "")
156         strRet = strprintf("help: unknown command: %s\n", strCommand.c_str());
157     strRet = strRet.substr(0,strRet.size()-1);
158     return strRet;
159 }
160
161
162 Value stop(const Array& params, bool fHelp)
163 {
164     if (fHelp || params.size() != 0)
165         throw runtime_error(
166             "stop\n"
167             "Stop bitcoin server.");
168
169     // Shutdown will take long enough that the response should get back
170     CreateThread(Shutdown, NULL);
171     return "bitcoin server stopping";
172 }
173
174
175 Value getblockcount(const Array& params, bool fHelp)
176 {
177     if (fHelp || params.size() != 0)
178         throw runtime_error(
179             "getblockcount\n"
180             "Returns the number of blocks in the longest block chain.");
181
182     return nBestHeight;
183 }
184
185
186 Value getblocknumber(const Array& params, bool fHelp)
187 {
188     if (fHelp || params.size() != 0)
189         throw runtime_error(
190             "getblocknumber\n"
191             "Returns the block number of the latest block in the longest block chain.");
192
193     return nBestHeight;
194 }
195
196
197 Value getconnectioncount(const Array& params, bool fHelp)
198 {
199     if (fHelp || params.size() != 0)
200         throw runtime_error(
201             "getconnectioncount\n"
202             "Returns the number of connections to other nodes.");
203
204     return (int)vNodes.size();
205 }
206
207
208 double GetDifficulty()
209 {
210     // Floating point number that is a multiple of the minimum difficulty,
211     // minimum difficulty = 1.0.
212
213     if (pindexBest == NULL)
214         return 1.0;
215     int nShift = (pindexBest->nBits >> 24) & 0xff;
216
217     double dDiff =
218         (double)0x0000ffff / (double)(pindexBest->nBits & 0x00ffffff);
219
220     while (nShift < 29)
221     {
222         dDiff *= 256.0;
223         nShift++;
224     }
225     while (nShift > 29)
226     {
227         dDiff /= 256.0;
228         nShift--;
229     }
230
231     return dDiff;
232 }
233
234 Value getdifficulty(const Array& params, bool fHelp)
235 {
236     if (fHelp || params.size() != 0)
237         throw runtime_error(
238             "getdifficulty\n"
239             "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
240
241     return GetDifficulty();
242 }
243
244
245 Value getgenerate(const Array& params, bool fHelp)
246 {
247     if (fHelp || params.size() != 0)
248         throw runtime_error(
249             "getgenerate\n"
250             "Returns true or false.");
251
252     return (bool)fGenerateBitcoins;
253 }
254
255
256 Value setgenerate(const Array& params, bool fHelp)
257 {
258     if (fHelp || params.size() < 1 || params.size() > 2)
259         throw runtime_error(
260             "setgenerate <generate> [genproclimit]\n"
261             "<generate> is true or false to turn generation on or off.\n"
262             "Generation is limited to [genproclimit] processors, -1 is unlimited.");
263
264     bool fGenerate = true;
265     if (params.size() > 0)
266         fGenerate = params[0].get_bool();
267
268     if (params.size() > 1)
269     {
270         int nGenProcLimit = params[1].get_int();
271         fLimitProcessors = (nGenProcLimit != -1);
272         WriteSetting("fLimitProcessors", fLimitProcessors);
273         if (nGenProcLimit != -1)
274             WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
275         if (nGenProcLimit == 0)
276             fGenerate = false;
277     }
278
279     GenerateBitcoins(fGenerate, pwalletMain);
280     return Value::null;
281 }
282
283
284 Value gethashespersec(const Array& params, bool fHelp)
285 {
286     if (fHelp || params.size() != 0)
287         throw runtime_error(
288             "gethashespersec\n"
289             "Returns a recent hashes per second performance measurement while generating.");
290
291     if (GetTimeMillis() - nHPSTimerStart > 8000)
292         return (boost::int64_t)0;
293     return (boost::int64_t)dHashesPerSec;
294 }
295
296
297 Value getinfo(const Array& params, bool fHelp)
298 {
299     if (fHelp || params.size() != 0)
300         throw runtime_error(
301             "getinfo\n"
302             "Returns an object containing various state info.");
303
304     Object obj;
305     obj.push_back(Pair("version",       (int)VERSION));
306     obj.push_back(Pair("balance",       ValueFromAmount(pwalletMain->GetBalance())));
307     obj.push_back(Pair("blocks",        (int)nBestHeight));
308     obj.push_back(Pair("connections",   (int)vNodes.size()));
309     obj.push_back(Pair("proxy",         (fUseProxy ? addrProxy.ToStringIPPort() : string())));
310     obj.push_back(Pair("generate",      (bool)fGenerateBitcoins));
311     obj.push_back(Pair("genproclimit",  (int)(fLimitProcessors ? nLimitProcessors : -1)));
312     obj.push_back(Pair("difficulty",    (double)GetDifficulty()));
313     obj.push_back(Pair("hashespersec",  gethashespersec(params, false)));
314     obj.push_back(Pair("testnet",       fTestNet));
315     obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
316     obj.push_back(Pair("keypoolsize",   pwalletMain->GetKeyPoolSize()));
317     obj.push_back(Pair("paytxfee",      ValueFromAmount(nTransactionFee)));
318     if (pwalletMain->IsCrypted())
319         obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
320     obj.push_back(Pair("errors",        GetWarnings("statusbar")));
321     return obj;
322 }
323
324
325 Value getnewaddress(const Array& params, bool fHelp)
326 {
327     if (fHelp || params.size() > 1)
328         throw runtime_error(
329             "getnewaddress [account]\n"
330             "Returns a new bitcoin address for receiving payments.  "
331             "If [account] is specified (recommended), it is added to the address book "
332             "so payments received with the address will be credited to [account].");
333
334     // Parse the account first so we don't generate a key if there's an error
335     string strAccount;
336     if (params.size() > 0)
337         strAccount = AccountFromValue(params[0]);
338
339     if (!pwalletMain->IsLocked())
340         pwalletMain->TopUpKeyPool();
341
342     // Generate a new key that is added to wallet
343     std::vector<unsigned char> newKey;
344     if (!pwalletMain->GetKeyFromPool(newKey, false))
345         throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
346     CBitcoinAddress address(newKey);
347
348     pwalletMain->SetAddressBookName(address, strAccount);
349
350     return address.ToString();
351 }
352
353
354 CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
355 {
356     CWalletDB walletdb(pwalletMain->strWalletFile);
357
358     CAccount account;
359     walletdb.ReadAccount(strAccount, account);
360
361     bool bKeyUsed = false;
362
363     // Check if the current key has been used
364     if (!account.vchPubKey.empty())
365     {
366         CScript scriptPubKey;
367         scriptPubKey.SetBitcoinAddress(account.vchPubKey);
368         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
369              it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
370              ++it)
371         {
372             const CWalletTx& wtx = (*it).second;
373             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
374                 if (txout.scriptPubKey == scriptPubKey)
375                     bKeyUsed = true;
376         }
377     }
378
379     // Generate a new key
380     if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
381     {
382         if (pwalletMain->GetKeyPoolSize() < 1)
383         {
384             if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
385                 throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first");
386
387             pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
388             walletdb.WriteAccount(strAccount, account);
389         }
390     }
391
392     return CBitcoinAddress(account.vchPubKey);
393 }
394
395 Value getaccountaddress(const Array& params, bool fHelp)
396 {
397     if (fHelp || params.size() != 1)
398         throw runtime_error(
399             "getaccountaddress <account>\n"
400             "Returns the current bitcoin address for receiving payments to this account.");
401
402     // Parse the account first so we don't generate a key if there's an error
403     string strAccount = AccountFromValue(params[0]);
404
405     Value ret;
406
407     ret = GetAccountAddress(strAccount).ToString();
408
409     return ret;
410 }
411
412
413
414 Value setaccount(const Array& params, bool fHelp)
415 {
416     if (fHelp || params.size() < 1 || params.size() > 2)
417         throw runtime_error(
418             "setaccount <bitcoinaddress> <account>\n"
419             "Sets the account associated with the given address.");
420
421     CBitcoinAddress address(params[0].get_str());
422     if (!address.IsValid())
423         throw JSONRPCError(-5, "Invalid bitcoin address");
424
425
426     string strAccount;
427     if (params.size() > 1)
428         strAccount = AccountFromValue(params[1]);
429
430     // Detect when changing the account of an address that is the 'unused current key' of another account:
431     if (pwalletMain->mapAddressBook.count(address))
432     {
433         string strOldAccount = pwalletMain->mapAddressBook[address];
434         if (address == GetAccountAddress(strOldAccount))
435             GetAccountAddress(strOldAccount, true);
436     }
437
438     pwalletMain->SetAddressBookName(address, strAccount);
439
440     return Value::null;
441 }
442
443
444 Value getaccount(const Array& params, bool fHelp)
445 {
446     if (fHelp || params.size() != 1)
447         throw runtime_error(
448             "getaccount <bitcoinaddress>\n"
449             "Returns the account associated with the given address.");
450
451     CBitcoinAddress address(params[0].get_str());
452     if (!address.IsValid())
453         throw JSONRPCError(-5, "Invalid bitcoin address");
454
455     string strAccount;
456     map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
457     if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
458         strAccount = (*mi).second;
459     return strAccount;
460 }
461
462
463 Value getaddressesbyaccount(const Array& params, bool fHelp)
464 {
465     if (fHelp || params.size() != 1)
466         throw runtime_error(
467             "getaddressesbyaccount <account>\n"
468             "Returns the list of addresses for the given account.");
469
470     string strAccount = AccountFromValue(params[0]);
471
472     // Find all addresses that have the given account
473     Array ret;
474     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
475     {
476         const CBitcoinAddress& address = item.first;
477         const string& strName = item.second;
478         if (strName == strAccount)
479             ret.push_back(address.ToString());
480     }
481     return ret;
482 }
483
484 Value settxfee(const Array& params, bool fHelp)
485 {
486     if (fHelp || params.size() < 1 || params.size() > 1)
487         throw runtime_error(
488             "settxfee <amount>\n"
489             "<amount> is a real and is rounded to the nearest 0.00000001");
490
491     // Amount
492     int64 nAmount = 0;
493     if (params[0].get_real() != 0.0)
494         nAmount = AmountFromValue(params[0]);        // rejects 0.0 amounts
495
496     nTransactionFee = nAmount;
497     return true;
498 }
499
500 Value sendtoaddress(const Array& params, bool fHelp)
501 {
502     if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
503         throw runtime_error(
504             "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
505             "<amount> is a real and is rounded to the nearest 0.00000001\n"
506             "requires wallet passphrase to be set with walletpassphrase first");
507     if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
508         throw runtime_error(
509             "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
510             "<amount> is a real and is rounded to the nearest 0.00000001");
511
512     CBitcoinAddress address(params[0].get_str());
513     if (!address.IsValid())
514         throw JSONRPCError(-5, "Invalid bitcoin address");
515
516     // Amount
517     int64 nAmount = AmountFromValue(params[1]);
518
519     // Wallet comments
520     CWalletTx wtx;
521     if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty())
522         wtx.mapValue["comment"] = params[2].get_str();
523     if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
524         wtx.mapValue["to"]      = params[3].get_str();
525
526     if (pwalletMain->IsLocked())
527         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
528
529     string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
530     if (strError != "")
531         throw JSONRPCError(-4, strError);
532
533     return wtx.GetHash().GetHex();
534 }
535
536
537 Value getreceivedbyaddress(const Array& params, bool fHelp)
538 {
539     if (fHelp || params.size() < 1 || params.size() > 2)
540         throw runtime_error(
541             "getreceivedbyaddress <bitcoinaddress> [minconf=1]\n"
542             "Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
543
544     // Bitcoin address
545     CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
546     CScript scriptPubKey;
547     if (!address.IsValid())
548         throw JSONRPCError(-5, "Invalid bitcoin address");
549     scriptPubKey.SetBitcoinAddress(address);
550     if (!IsMine(*pwalletMain,scriptPubKey))
551         return (double)0.0;
552
553     // Minimum confirmations
554     int nMinDepth = 1;
555     if (params.size() > 1)
556         nMinDepth = params[1].get_int();
557
558     // Tally
559     int64 nAmount = 0;
560     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
561     {
562         const CWalletTx& wtx = (*it).second;
563         if (wtx.IsCoinBase() || !wtx.IsFinal())
564             continue;
565
566         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
567             if (txout.scriptPubKey == scriptPubKey)
568                 if (wtx.GetDepthInMainChain() >= nMinDepth)
569                     nAmount += txout.nValue;
570     }
571
572     return  ValueFromAmount(nAmount);
573 }
574
575
576 void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress)
577 {
578     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
579     {
580         const CBitcoinAddress& address = item.first;
581         const string& strName = item.second;
582         if (strName == strAccount)
583             setAddress.insert(address);
584     }
585 }
586
587
588 Value getreceivedbyaccount(const Array& params, bool fHelp)
589 {
590     if (fHelp || params.size() < 1 || params.size() > 2)
591         throw runtime_error(
592             "getreceivedbyaccount <account> [minconf=1]\n"
593             "Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.");
594
595     // Minimum confirmations
596     int nMinDepth = 1;
597     if (params.size() > 1)
598         nMinDepth = params[1].get_int();
599
600     // Get the set of pub keys that have the label
601     string strAccount = AccountFromValue(params[0]);
602     set<CBitcoinAddress> setAddress;
603     GetAccountAddresses(strAccount, setAddress);
604
605     // Tally
606     int64 nAmount = 0;
607     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
608     {
609         const CWalletTx& wtx = (*it).second;
610         if (wtx.IsCoinBase() || !wtx.IsFinal())
611             continue;
612
613         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
614         {
615             CBitcoinAddress address;
616             if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address))
617                 if (wtx.GetDepthInMainChain() >= nMinDepth)
618                     nAmount += txout.nValue;
619         }
620     }
621
622     return (double)nAmount / (double)COIN;
623 }
624
625
626 int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
627 {
628     int64 nBalance = 0;
629
630     // Tally wallet transactions
631     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
632     {
633         const CWalletTx& wtx = (*it).second;
634         if (!wtx.IsFinal())
635             continue;
636
637         int64 nGenerated, nReceived, nSent, nFee;
638         wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee);
639
640         if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
641             nBalance += nReceived;
642         nBalance += nGenerated - nSent - nFee;
643     }
644
645     // Tally internal accounting entries
646     nBalance += walletdb.GetAccountCreditDebit(strAccount);
647
648     return nBalance;
649 }
650
651 int64 GetAccountBalance(const string& strAccount, int nMinDepth)
652 {
653     CWalletDB walletdb(pwalletMain->strWalletFile);
654     return GetAccountBalance(walletdb, strAccount, nMinDepth);
655 }
656
657
658 Value getbalance(const Array& params, bool fHelp)
659 {
660     if (fHelp || params.size() > 2)
661         throw runtime_error(
662             "getbalance [account] [minconf=1]\n"
663             "If [account] is not specified, returns the server's total available balance.\n"
664             "If [account] is specified, returns the balance in the account.");
665
666     if (params.size() == 0)
667         return  ValueFromAmount(pwalletMain->GetBalance());
668
669     int nMinDepth = 1;
670     if (params.size() > 1)
671         nMinDepth = params[1].get_int();
672
673     if (params[0].get_str() == "*") {
674         // Calculate total balance a different way from GetBalance()
675         // (GetBalance() sums up all unspent TxOuts)
676         // getbalance and getbalance '*' should always return the same number.
677         int64 nBalance = 0;
678         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
679         {
680             const CWalletTx& wtx = (*it).second;
681             if (!wtx.IsFinal())
682                 continue;
683
684             int64 allGeneratedImmature, allGeneratedMature, allFee;
685             allGeneratedImmature = allGeneratedMature = allFee = 0;
686             string strSentAccount;
687             list<pair<CBitcoinAddress, int64> > listReceived;
688             list<pair<CBitcoinAddress, int64> > listSent;
689             wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
690             if (wtx.GetDepthInMainChain() >= nMinDepth)
691                 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
692                     nBalance += r.second;
693             BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent)
694                 nBalance -= r.second;
695             nBalance -= allFee;
696             nBalance += allGeneratedMature;
697         }
698         return  ValueFromAmount(nBalance);
699     }
700
701     string strAccount = AccountFromValue(params[0]);
702
703     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
704
705     return ValueFromAmount(nBalance);
706 }
707
708
709 Value movecmd(const Array& params, bool fHelp)
710 {
711     if (fHelp || params.size() < 3 || params.size() > 5)
712         throw runtime_error(
713             "move <fromaccount> <toaccount> <amount> [minconf=1] [comment]\n"
714             "Move from one account in your wallet to another.");
715
716     string strFrom = AccountFromValue(params[0]);
717     string strTo = AccountFromValue(params[1]);
718     int64 nAmount = AmountFromValue(params[2]);
719     if (params.size() > 3)
720         // unused parameter, used to be nMinDepth, keep type-checking it though
721         (void)params[3].get_int();
722     string strComment;
723     if (params.size() > 4)
724         strComment = params[4].get_str();
725
726     CWalletDB walletdb(pwalletMain->strWalletFile);
727     walletdb.TxnBegin();
728
729     int64 nNow = GetAdjustedTime();
730
731     // Debit
732     CAccountingEntry debit;
733     debit.strAccount = strFrom;
734     debit.nCreditDebit = -nAmount;
735     debit.nTime = nNow;
736     debit.strOtherAccount = strTo;
737     debit.strComment = strComment;
738     walletdb.WriteAccountingEntry(debit);
739
740     // Credit
741     CAccountingEntry credit;
742     credit.strAccount = strTo;
743     credit.nCreditDebit = nAmount;
744     credit.nTime = nNow;
745     credit.strOtherAccount = strFrom;
746     credit.strComment = strComment;
747     walletdb.WriteAccountingEntry(credit);
748
749     walletdb.TxnCommit();
750
751     return true;
752 }
753
754
755 Value sendfrom(const Array& params, bool fHelp)
756 {
757     if (pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6))
758         throw runtime_error(
759             "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
760             "<amount> is a real and is rounded to the nearest 0.00000001\n"
761             "requires wallet passphrase to be set with walletpassphrase first");
762     if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6))
763         throw runtime_error(
764             "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
765             "<amount> is a real and is rounded to the nearest 0.00000001");
766
767     string strAccount = AccountFromValue(params[0]);
768     CBitcoinAddress address(params[1].get_str());
769     if (!address.IsValid())
770         throw JSONRPCError(-5, "Invalid bitcoin address");
771     int64 nAmount = AmountFromValue(params[2]);
772     int nMinDepth = 1;
773     if (params.size() > 3)
774         nMinDepth = params[3].get_int();
775
776     CWalletTx wtx;
777     wtx.strFromAccount = strAccount;
778     if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty())
779         wtx.mapValue["comment"] = params[4].get_str();
780     if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty())
781         wtx.mapValue["to"]      = params[5].get_str();
782
783     if (pwalletMain->IsLocked())
784         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
785
786     // Check funds
787     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
788     if (nAmount > nBalance)
789         throw JSONRPCError(-6, "Account has insufficient funds");
790
791     // Send
792     string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
793     if (strError != "")
794         throw JSONRPCError(-4, strError);
795
796     return wtx.GetHash().GetHex();
797 }
798
799
800 Value sendmany(const Array& params, bool fHelp)
801 {
802     if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
803         throw runtime_error(
804             "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
805             "amounts are double-precision floating point numbers\n"
806             "requires wallet passphrase to be set with walletpassphrase first");
807     if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
808         throw runtime_error(
809             "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
810             "amounts are double-precision floating point numbers");
811
812     string strAccount = AccountFromValue(params[0]);
813     Object sendTo = params[1].get_obj();
814     int nMinDepth = 1;
815     if (params.size() > 2)
816         nMinDepth = params[2].get_int();
817
818     CWalletTx wtx;
819     wtx.strFromAccount = strAccount;
820     if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
821         wtx.mapValue["comment"] = params[3].get_str();
822
823     set<CBitcoinAddress> setAddress;
824     vector<pair<CScript, int64> > vecSend;
825
826     int64 totalAmount = 0;
827     BOOST_FOREACH(const Pair& s, sendTo)
828     {
829         CBitcoinAddress address(s.name_);
830         if (!address.IsValid())
831             throw JSONRPCError(-5, string("Invalid bitcoin address:")+s.name_);
832
833         if (setAddress.count(address))
834             throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
835         setAddress.insert(address);
836
837         CScript scriptPubKey;
838         scriptPubKey.SetBitcoinAddress(address);
839         int64 nAmount = AmountFromValue(s.value_); 
840         totalAmount += nAmount;
841
842         vecSend.push_back(make_pair(scriptPubKey, nAmount));
843     }
844
845     if (pwalletMain->IsLocked())
846         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
847
848     // Check funds
849     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
850     if (totalAmount > nBalance)
851         throw JSONRPCError(-6, "Account has insufficient funds");
852
853     // Send
854     CReserveKey keyChange(pwalletMain);
855     int64 nFeeRequired = 0;
856     bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
857     if (!fCreated)
858     {
859         if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
860             throw JSONRPCError(-6, "Insufficient funds");
861         throw JSONRPCError(-4, "Transaction creation failed");
862     }
863     if (!pwalletMain->CommitTransaction(wtx, keyChange))
864         throw JSONRPCError(-4, "Transaction commit failed");
865
866     return wtx.GetHash().GetHex();
867 }
868
869
870 struct tallyitem
871 {
872     int64 nAmount;
873     int nConf;
874     tallyitem()
875     {
876         nAmount = 0;
877         nConf = INT_MAX;
878     }
879 };
880
881 Value ListReceived(const Array& params, bool fByAccounts)
882 {
883     // Minimum confirmations
884     int nMinDepth = 1;
885     if (params.size() > 0)
886         nMinDepth = params[0].get_int();
887
888     // Whether to include empty accounts
889     bool fIncludeEmpty = false;
890     if (params.size() > 1)
891         fIncludeEmpty = params[1].get_bool();
892
893     // Tally
894     map<CBitcoinAddress, tallyitem> mapTally;
895     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
896     {
897         const CWalletTx& wtx = (*it).second;
898         if (wtx.IsCoinBase() || !wtx.IsFinal())
899             continue;
900
901         int nDepth = wtx.GetDepthInMainChain();
902         if (nDepth < nMinDepth)
903             continue;
904
905         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
906         {
907             CBitcoinAddress address;
908             if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid())
909                 continue;
910
911             tallyitem& item = mapTally[address];
912             item.nAmount += txout.nValue;
913             item.nConf = min(item.nConf, nDepth);
914         }
915     }
916
917     // Reply
918     Array ret;
919     map<string, tallyitem> mapAccountTally;
920     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
921     {
922         const CBitcoinAddress& address = item.first;
923         const string& strAccount = item.second;
924         map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
925         if (it == mapTally.end() && !fIncludeEmpty)
926             continue;
927
928         int64 nAmount = 0;
929         int nConf = INT_MAX;
930         if (it != mapTally.end())
931         {
932             nAmount = (*it).second.nAmount;
933             nConf = (*it).second.nConf;
934         }
935
936         if (fByAccounts)
937         {
938             tallyitem& item = mapAccountTally[strAccount];
939             item.nAmount += nAmount;
940             item.nConf = min(item.nConf, nConf);
941         }
942         else
943         {
944             Object obj;
945             obj.push_back(Pair("address",       address.ToString()));
946             obj.push_back(Pair("account",       strAccount));
947             obj.push_back(Pair("label",         strAccount)); // deprecated
948             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
949             obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
950             ret.push_back(obj);
951         }
952     }
953
954     if (fByAccounts)
955     {
956         for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
957         {
958             int64 nAmount = (*it).second.nAmount;
959             int nConf = (*it).second.nConf;
960             Object obj;
961             obj.push_back(Pair("account",       (*it).first));
962             obj.push_back(Pair("label",         (*it).first)); // deprecated
963             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
964             obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
965             ret.push_back(obj);
966         }
967     }
968
969     return ret;
970 }
971
972 Value listreceivedbyaddress(const Array& params, bool fHelp)
973 {
974     if (fHelp || params.size() > 2)
975         throw runtime_error(
976             "listreceivedbyaddress [minconf=1] [includeempty=false]\n"
977             "[minconf] is the minimum number of confirmations before payments are included.\n"
978             "[includeempty] whether to include addresses that haven't received any payments.\n"
979             "Returns an array of objects containing:\n"
980             "  \"address\" : receiving address\n"
981             "  \"account\" : the account of the receiving address\n"
982             "  \"amount\" : total amount received by the address\n"
983             "  \"confirmations\" : number of confirmations of the most recent transaction included");
984
985     return ListReceived(params, false);
986 }
987
988 Value listreceivedbyaccount(const Array& params, bool fHelp)
989 {
990     if (fHelp || params.size() > 2)
991         throw runtime_error(
992             "listreceivedbyaccount [minconf=1] [includeempty=false]\n"
993             "[minconf] is the minimum number of confirmations before payments are included.\n"
994             "[includeempty] whether to include accounts that haven't received any payments.\n"
995             "Returns an array of objects containing:\n"
996             "  \"account\" : the account of the receiving addresses\n"
997             "  \"amount\" : total amount received by addresses with this account\n"
998             "  \"confirmations\" : number of confirmations of the most recent transaction included");
999
1000     return ListReceived(params, true);
1001 }
1002
1003 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
1004 {
1005     int64 nGeneratedImmature, nGeneratedMature, nFee;
1006     string strSentAccount;
1007     list<pair<CBitcoinAddress, int64> > listReceived;
1008     list<pair<CBitcoinAddress, int64> > listSent;
1009     wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
1010
1011     bool fAllAccounts = (strAccount == string("*"));
1012
1013     // Generated blocks assigned to account ""
1014     if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == ""))
1015     {
1016         Object entry;
1017         entry.push_back(Pair("account", string("")));
1018         if (nGeneratedImmature)
1019         {
1020             entry.push_back(Pair("category", wtx.GetDepthInMainChain() ? "immature" : "orphan"));
1021             entry.push_back(Pair("amount", ValueFromAmount(nGeneratedImmature)));
1022         }
1023         else
1024         {
1025             entry.push_back(Pair("category", "generate"));
1026             entry.push_back(Pair("amount", ValueFromAmount(nGeneratedMature)));
1027         }
1028         if (fLong)
1029             WalletTxToJSON(wtx, entry);
1030         ret.push_back(entry);
1031     }
1032
1033     // Sent
1034     if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1035     {
1036         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
1037         {
1038             Object entry;
1039             entry.push_back(Pair("account", strSentAccount));
1040             entry.push_back(Pair("address", s.first.ToString()));
1041             entry.push_back(Pair("category", "send"));
1042             entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
1043             entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1044             if (fLong)
1045                 WalletTxToJSON(wtx, entry);
1046             ret.push_back(entry);
1047         }
1048     }
1049
1050     // Received
1051     if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1052         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
1053         {
1054             string account;
1055             if (pwalletMain->mapAddressBook.count(r.first))
1056                 account = pwalletMain->mapAddressBook[r.first];
1057             if (fAllAccounts || (account == strAccount))
1058             {
1059                 Object entry;
1060                 entry.push_back(Pair("account", account));
1061                 entry.push_back(Pair("address", r.first.ToString()));
1062                 entry.push_back(Pair("category", "receive"));
1063                 entry.push_back(Pair("amount", ValueFromAmount(r.second)));
1064                 if (fLong)
1065                     WalletTxToJSON(wtx, entry);
1066                 ret.push_back(entry);
1067             }
1068         }
1069 }
1070
1071 void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret)
1072 {
1073     bool fAllAccounts = (strAccount == string("*"));
1074
1075     if (fAllAccounts || acentry.strAccount == strAccount)
1076     {
1077         Object entry;
1078         entry.push_back(Pair("account", acentry.strAccount));
1079         entry.push_back(Pair("category", "move"));
1080         entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
1081         entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1082         entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1083         entry.push_back(Pair("comment", acentry.strComment));
1084         ret.push_back(entry);
1085     }
1086 }
1087
1088 Value listtransactions(const Array& params, bool fHelp)
1089 {
1090     if (fHelp || params.size() > 3)
1091         throw runtime_error(
1092             "listtransactions [account] [count=10] [from=0]\n"
1093             "Returns up to [count] most recent transactions skipping the first [from] transactions for account [account].");
1094
1095     string strAccount = "*";
1096     if (params.size() > 0)
1097         strAccount = params[0].get_str();
1098     int nCount = 10;
1099     if (params.size() > 1)
1100         nCount = params[1].get_int();
1101     int nFrom = 0;
1102     if (params.size() > 2)
1103         nFrom = params[2].get_int();
1104
1105     Array ret;
1106     CWalletDB walletdb(pwalletMain->strWalletFile);
1107
1108     // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
1109     typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
1110     typedef multimap<int64, TxPair > TxItems;
1111     TxItems txByTime;
1112
1113     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1114     {
1115         CWalletTx* wtx = &((*it).second);
1116         txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
1117     }
1118     list<CAccountingEntry> acentries;
1119     walletdb.ListAccountCreditDebit(strAccount, acentries);
1120     BOOST_FOREACH(CAccountingEntry& entry, acentries)
1121     {
1122         txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
1123     }
1124
1125     // Now: iterate backwards until we have nCount items to return:
1126     TxItems::reverse_iterator it = txByTime.rbegin();
1127     if (txByTime.size() > nFrom) std::advance(it, nFrom);
1128     for (; it != txByTime.rend(); ++it)
1129     {
1130         CWalletTx *const pwtx = (*it).second.first;
1131         if (pwtx != 0)
1132             ListTransactions(*pwtx, strAccount, 0, true, ret);
1133         CAccountingEntry *const pacentry = (*it).second.second;
1134         if (pacentry != 0)
1135             AcentryToJSON(*pacentry, strAccount, ret);
1136
1137         if (ret.size() >= nCount) break;
1138     }
1139     // ret is now newest to oldest
1140     
1141     // Make sure we return only last nCount items (sends-to-self might give us an extra):
1142     if (ret.size() > nCount)
1143     {
1144         Array::iterator last = ret.begin();
1145         std::advance(last, nCount);
1146         ret.erase(last, ret.end());
1147     }
1148     std::reverse(ret.begin(), ret.end()); // oldest to newest
1149
1150     return ret;
1151 }
1152
1153 Value listaccounts(const Array& params, bool fHelp)
1154 {
1155     if (fHelp || params.size() > 1)
1156         throw runtime_error(
1157             "listaccounts [minconf=1]\n"
1158             "Returns Object that has account names as keys, account balances as values.");
1159
1160     int nMinDepth = 1;
1161     if (params.size() > 0)
1162         nMinDepth = params[0].get_int();
1163
1164     map<string, int64> mapAccountBalances;
1165     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
1166         if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
1167             mapAccountBalances[entry.second] = 0;
1168     }
1169
1170     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
1171     {
1172         const CWalletTx& wtx = (*it).second;
1173         int64 nGeneratedImmature, nGeneratedMature, nFee;
1174         string strSentAccount;
1175         list<pair<CBitcoinAddress, int64> > listReceived;
1176         list<pair<CBitcoinAddress, int64> > listSent;
1177         wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
1178         mapAccountBalances[strSentAccount] -= nFee;
1179         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
1180             mapAccountBalances[strSentAccount] -= s.second;
1181         if (wtx.GetDepthInMainChain() >= nMinDepth)
1182         {
1183             mapAccountBalances[""] += nGeneratedMature;
1184             BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
1185                 if (pwalletMain->mapAddressBook.count(r.first))
1186                     mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
1187                 else
1188                     mapAccountBalances[""] += r.second;
1189         }
1190     }
1191
1192     list<CAccountingEntry> acentries;
1193     CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
1194     BOOST_FOREACH(const CAccountingEntry& entry, acentries)
1195         mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1196
1197     Object ret;
1198     BOOST_FOREACH(const PAIRTYPE(string, int64)& accountBalance, mapAccountBalances) {
1199         ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1200     }
1201     return ret;
1202 }
1203
1204 Value gettransaction(const Array& params, bool fHelp)
1205 {
1206     if (fHelp || params.size() != 1)
1207         throw runtime_error(
1208             "gettransaction <txid>\n"
1209             "Get detailed information about <txid>");
1210
1211     uint256 hash;
1212     hash.SetHex(params[0].get_str());
1213
1214     Object entry;
1215
1216     if (!pwalletMain->mapWallet.count(hash))
1217         throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
1218     const CWalletTx& wtx = pwalletMain->mapWallet[hash];
1219
1220     int64 nCredit = wtx.GetCredit();
1221     int64 nDebit = wtx.GetDebit();
1222     int64 nNet = nCredit - nDebit;
1223     int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
1224
1225     entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
1226     if (wtx.IsFromMe())
1227         entry.push_back(Pair("fee", ValueFromAmount(nFee)));
1228
1229     WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
1230
1231     Array details;
1232     ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
1233     entry.push_back(Pair("details", details));
1234
1235     return entry;
1236 }
1237
1238
1239 Value backupwallet(const Array& params, bool fHelp)
1240 {
1241     if (fHelp || params.size() != 1)
1242         throw runtime_error(
1243             "backupwallet <destination>\n"
1244             "Safely copies wallet.dat to destination, which can be a directory or a path with filename.");
1245
1246     string strDest = params[0].get_str();
1247     BackupWallet(*pwalletMain, strDest);
1248
1249     return Value::null;
1250 }
1251
1252
1253 Value keypoolrefill(const Array& params, bool fHelp)
1254 {
1255     if (pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
1256         throw runtime_error(
1257             "keypoolrefill\n"
1258             "Fills the keypool, requires wallet passphrase to be set.");
1259     if (!pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
1260         throw runtime_error(
1261             "keypoolrefill\n"
1262             "Fills the keypool.");
1263
1264     if (pwalletMain->IsLocked())
1265         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
1266
1267     pwalletMain->TopUpKeyPool();
1268
1269     if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
1270         throw JSONRPCError(-4, "Error refreshing keypool.");
1271
1272     return Value::null;
1273 }
1274
1275
1276 void ThreadTopUpKeyPool(void* parg)
1277 {
1278     pwalletMain->TopUpKeyPool();
1279 }
1280
1281 void ThreadCleanWalletPassphrase(void* parg)
1282 {
1283     int64 nMyWakeTime = GetTime() + *((int*)parg);
1284
1285     if (nWalletUnlockTime == 0)
1286     {
1287         CRITICAL_BLOCK(cs_nWalletUnlockTime)
1288         {
1289             nWalletUnlockTime = nMyWakeTime;
1290         }
1291
1292         while (GetTime() < nWalletUnlockTime)
1293             Sleep(GetTime() - nWalletUnlockTime);
1294
1295         CRITICAL_BLOCK(cs_nWalletUnlockTime)
1296         {
1297             nWalletUnlockTime = 0;
1298         }
1299     }
1300     else
1301     {
1302         CRITICAL_BLOCK(cs_nWalletUnlockTime)
1303         {
1304             if (nWalletUnlockTime < nMyWakeTime)
1305                 nWalletUnlockTime = nMyWakeTime;
1306         }
1307         free(parg);
1308         return;
1309     }
1310
1311     pwalletMain->Lock();
1312
1313     delete (int*)parg;
1314 }
1315
1316 Value walletpassphrase(const Array& params, bool fHelp)
1317 {
1318     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1319         throw runtime_error(
1320             "walletpassphrase <passphrase> <timeout>\n"
1321             "Stores the wallet decryption key in memory for <timeout> seconds.");
1322     if (fHelp)
1323         return true;
1324     if (!pwalletMain->IsCrypted())
1325         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
1326
1327     if (!pwalletMain->IsLocked())
1328         throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
1329
1330     // Note that the walletpassphrase is stored in params[0] which is not mlock()ed
1331     string strWalletPass;
1332     strWalletPass.reserve(100);
1333     mlock(&strWalletPass[0], strWalletPass.capacity());
1334     strWalletPass = params[0].get_str();
1335
1336     if (strWalletPass.length() > 0)
1337     {
1338         if (!pwalletMain->Unlock(strWalletPass))
1339         {
1340             fill(strWalletPass.begin(), strWalletPass.end(), '\0');
1341             munlock(&strWalletPass[0], strWalletPass.capacity());
1342             throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
1343         }
1344         fill(strWalletPass.begin(), strWalletPass.end(), '\0');
1345         munlock(&strWalletPass[0], strWalletPass.capacity());
1346     }
1347     else
1348         throw runtime_error(
1349             "walletpassphrase <passphrase> <timeout>\n"
1350             "Stores the wallet decryption key in memory for <timeout> seconds.");
1351
1352     CreateThread(ThreadTopUpKeyPool, NULL);
1353     int* pnSleepTime = new int(params[1].get_int());
1354     CreateThread(ThreadCleanWalletPassphrase, pnSleepTime);
1355
1356     return Value::null;
1357 }
1358
1359
1360 Value walletpassphrasechange(const Array& params, bool fHelp)
1361 {
1362     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
1363         throw runtime_error(
1364             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1365             "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1366     if (fHelp)
1367         return true;
1368     if (!pwalletMain->IsCrypted())
1369         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
1370
1371     string strOldWalletPass;
1372     strOldWalletPass.reserve(100);
1373     mlock(&strOldWalletPass[0], strOldWalletPass.capacity());
1374     strOldWalletPass = params[0].get_str();
1375
1376     string strNewWalletPass;
1377     strNewWalletPass.reserve(100);
1378     mlock(&strNewWalletPass[0], strNewWalletPass.capacity());
1379     strNewWalletPass = params[1].get_str();
1380
1381     if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
1382         throw runtime_error(
1383             "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
1384             "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
1385
1386     if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
1387     {
1388         fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
1389         fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
1390         munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
1391         munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
1392         throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
1393     }
1394     fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
1395     fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
1396     munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
1397     munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
1398
1399     return Value::null;
1400 }
1401
1402
1403 Value walletlock(const Array& params, bool fHelp)
1404 {
1405     if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0))
1406         throw runtime_error(
1407             "walletlock\n"
1408             "Removes the wallet encryption key from memory, locking the wallet.\n"
1409             "After calling this method, you will need to call walletpassphrase again\n"
1410             "before being able to call any methods which require the wallet to be unlocked.");
1411     if (fHelp)
1412         return true;
1413     if (!pwalletMain->IsCrypted())
1414         throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
1415
1416     pwalletMain->Lock();
1417     CRITICAL_BLOCK(cs_nWalletUnlockTime)
1418     {
1419         nWalletUnlockTime = 0;
1420     }
1421
1422     return Value::null;
1423 }
1424
1425
1426 Value encryptwallet(const Array& params, bool fHelp)
1427 {
1428     if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
1429         throw runtime_error(
1430             "encryptwallet <passphrase>\n"
1431             "Encrypts the wallet with <passphrase>.");
1432     if (fHelp)
1433         return true;
1434     if (pwalletMain->IsCrypted())
1435         throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called.");
1436
1437     string strWalletPass;
1438     strWalletPass.reserve(100);
1439     mlock(&strWalletPass[0], strWalletPass.capacity());
1440     strWalletPass = params[0].get_str();
1441
1442     if (strWalletPass.length() < 1)
1443         throw runtime_error(
1444             "encryptwallet <passphrase>\n"
1445             "Encrypts the wallet with <passphrase>.");
1446
1447     if (!pwalletMain->EncryptWallet(strWalletPass))
1448     {
1449         fill(strWalletPass.begin(), strWalletPass.end(), '\0');
1450         munlock(&strWalletPass[0], strWalletPass.capacity());
1451         throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
1452     }
1453     fill(strWalletPass.begin(), strWalletPass.end(), '\0');
1454     munlock(&strWalletPass[0], strWalletPass.capacity());
1455
1456     return Value::null;
1457 }
1458
1459
1460 Value validateaddress(const Array& params, bool fHelp)
1461 {
1462     if (fHelp || params.size() != 1)
1463         throw runtime_error(
1464             "validateaddress <bitcoinaddress>\n"
1465             "Return information about <bitcoinaddress>.");
1466
1467     CBitcoinAddress address(params[0].get_str());
1468     bool isValid = address.IsValid();
1469
1470     Object ret;
1471     ret.push_back(Pair("isvalid", isValid));
1472     if (isValid)
1473     {
1474         // Call Hash160ToAddress() so we always return current ADDRESSVERSION
1475         // version of the address:
1476         string currentAddress = address.ToString();
1477         ret.push_back(Pair("address", currentAddress));
1478         ret.push_back(Pair("ismine", (pwalletMain->HaveKey(address) > 0)));
1479         if (pwalletMain->mapAddressBook.count(address))
1480             ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
1481     }
1482     return ret;
1483 }
1484
1485
1486 Value getwork(const Array& params, bool fHelp)
1487 {
1488     if (fHelp || params.size() > 1)
1489         throw runtime_error(
1490             "getwork [data]\n"
1491             "If [data] is not specified, returns formatted hash data to work on:\n"
1492             "  \"midstate\" : precomputed hash state after hashing the first half of the data\n"
1493             "  \"data\" : block data\n"
1494             "  \"hash1\" : formatted hash buffer for second hash\n"
1495             "  \"target\" : little endian hash target\n"
1496             "If [data] is specified, tries to solve the block and returns true if it was successful.");
1497
1498     if (vNodes.empty())
1499         throw JSONRPCError(-9, "Bitcoin is not connected!");
1500
1501     if (IsInitialBlockDownload())
1502         throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
1503
1504     static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock;
1505     static vector<CBlock*> vNewBlock;
1506     static CReserveKey reservekey(pwalletMain);
1507
1508     if (params.size() == 0)
1509     {
1510         // Update block
1511         static unsigned int nTransactionsUpdatedLast;
1512         static CBlockIndex* pindexPrev;
1513         static int64 nStart;
1514         static CBlock* pblock;
1515         if (pindexPrev != pindexBest ||
1516             (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
1517         {
1518             if (pindexPrev != pindexBest)
1519             {
1520                 // Deallocate old blocks since they're obsolete now
1521                 mapNewBlock.clear();
1522                 BOOST_FOREACH(CBlock* pblock, vNewBlock)
1523                     delete pblock;
1524                 vNewBlock.clear();
1525             }
1526             nTransactionsUpdatedLast = nTransactionsUpdated;
1527             pindexPrev = pindexBest;
1528             nStart = GetTime();
1529
1530             // Create new block
1531             pblock = CreateNewBlock(reservekey);
1532             if (!pblock)
1533                 throw JSONRPCError(-7, "Out of memory");
1534             vNewBlock.push_back(pblock);
1535         }
1536
1537         // Update nTime
1538         pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
1539         pblock->nNonce = 0;
1540
1541         // Update nExtraNonce
1542         static unsigned int nExtraNonce = 0;
1543         static int64 nPrevTime = 0;
1544         IncrementExtraNonce(pblock, pindexPrev, nExtraNonce, nPrevTime);
1545
1546         // Save
1547         mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, nExtraNonce);
1548
1549         // Prebuild hash buffers
1550         char pmidstate[32];
1551         char pdata[128];
1552         char phash1[64];
1553         FormatHashBuffers(pblock, pmidstate, pdata, phash1);
1554
1555         uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
1556
1557         Object result;
1558         result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate))));
1559         result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
1560         result.push_back(Pair("hash1",    HexStr(BEGIN(phash1), END(phash1))));
1561         result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));
1562         return result;
1563     }
1564     else
1565     {
1566         // Parse parameters
1567         vector<unsigned char> vchData = ParseHex(params[0].get_str());
1568         if (vchData.size() != 128)
1569             throw JSONRPCError(-8, "Invalid parameter");
1570         CBlock* pdata = (CBlock*)&vchData[0];
1571
1572         // Byte reverse
1573         for (int i = 0; i < 128/4; i++)
1574             ((unsigned int*)pdata)[i] = CryptoPP::ByteReverse(((unsigned int*)pdata)[i]);
1575
1576         // Get saved block
1577         if (!mapNewBlock.count(pdata->hashMerkleRoot))
1578             return false;
1579         CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
1580         unsigned int nExtraNonce = mapNewBlock[pdata->hashMerkleRoot].second;
1581
1582         pblock->nTime = pdata->nTime;
1583         pblock->nNonce = pdata->nNonce;
1584         pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce);
1585         pblock->hashMerkleRoot = pblock->BuildMerkleTree();
1586
1587         return CheckWork(pblock, *pwalletMain, reservekey);
1588     }
1589 }
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601 //
1602 // Call Table
1603 //
1604
1605 pair<string, rpcfn_type> pCallTable[] =
1606 {
1607     make_pair("help",                   &help),
1608     make_pair("stop",                   &stop),
1609     make_pair("getblockcount",          &getblockcount),
1610     make_pair("getblocknumber",         &getblocknumber),
1611     make_pair("getconnectioncount",     &getconnectioncount),
1612     make_pair("getdifficulty",          &getdifficulty),
1613     make_pair("getgenerate",            &getgenerate),
1614     make_pair("setgenerate",            &setgenerate),
1615     make_pair("gethashespersec",        &gethashespersec),
1616     make_pair("getinfo",                &getinfo),
1617     make_pair("getnewaddress",          &getnewaddress),
1618     make_pair("getaccountaddress",      &getaccountaddress),
1619     make_pair("setaccount",             &setaccount),
1620     make_pair("setlabel",               &setaccount), // deprecated
1621     make_pair("getaccount",             &getaccount),
1622     make_pair("getlabel",               &getaccount), // deprecated
1623     make_pair("getaddressesbyaccount",  &getaddressesbyaccount),
1624     make_pair("getaddressesbylabel",    &getaddressesbyaccount), // deprecated
1625     make_pair("sendtoaddress",          &sendtoaddress),
1626     make_pair("getamountreceived",      &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress
1627     make_pair("getallreceived",         &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress
1628     make_pair("getreceivedbyaddress",   &getreceivedbyaddress),
1629     make_pair("getreceivedbyaccount",   &getreceivedbyaccount),
1630     make_pair("getreceivedbylabel",     &getreceivedbyaccount), // deprecated
1631     make_pair("listreceivedbyaddress",  &listreceivedbyaddress),
1632     make_pair("listreceivedbyaccount",  &listreceivedbyaccount),
1633     make_pair("listreceivedbylabel",    &listreceivedbyaccount), // deprecated
1634     make_pair("backupwallet",           &backupwallet),
1635     make_pair("keypoolrefill",          &keypoolrefill),
1636     make_pair("walletpassphrase",       &walletpassphrase),
1637     make_pair("walletpassphrasechange", &walletpassphrasechange),
1638     make_pair("walletlock",             &walletlock),
1639     make_pair("encryptwallet",          &encryptwallet),
1640     make_pair("validateaddress",        &validateaddress),
1641     make_pair("getbalance",             &getbalance),
1642     make_pair("move",                   &movecmd),
1643     make_pair("sendfrom",               &sendfrom),
1644     make_pair("sendmany",               &sendmany),
1645     make_pair("gettransaction",         &gettransaction),
1646     make_pair("listtransactions",       &listtransactions),
1647     make_pair("getwork",                &getwork),
1648     make_pair("listaccounts",           &listaccounts),
1649     make_pair("settxfee",               &settxfee),
1650 };
1651 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
1652
1653 string pAllowInSafeMode[] =
1654 {
1655     "help",
1656     "stop",
1657     "getblockcount",
1658     "getblocknumber",
1659     "getconnectioncount",
1660     "getdifficulty",
1661     "getgenerate",
1662     "setgenerate",
1663     "gethashespersec",
1664     "getinfo",
1665     "getnewaddress",
1666     "getaccountaddress",
1667     "setlabel", // deprecated
1668     "getaccount",
1669     "getlabel", // deprecated
1670     "getaddressesbyaccount",
1671     "getaddressesbylabel", // deprecated
1672     "backupwallet",
1673     "keypoolrefill",
1674     "walletpassphrase",
1675     "walletlock",
1676     "validateaddress",
1677     "getwork",
1678 };
1679 set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
1680
1681
1682
1683
1684 //
1685 // HTTP protocol
1686 //
1687 // This ain't Apache.  We're just using HTTP header for the length field
1688 // and to be compatible with other JSON-RPC implementations.
1689 //
1690
1691 string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
1692 {
1693     ostringstream s;
1694     s << "POST / HTTP/1.1\r\n"
1695       << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n"
1696       << "Host: 127.0.0.1\r\n"
1697       << "Content-Type: application/json\r\n"
1698       << "Content-Length: " << strMsg.size() << "\r\n"
1699       << "Accept: application/json\r\n";
1700     BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders)
1701         s << item.first << ": " << item.second << "\r\n";
1702     s << "\r\n" << strMsg;
1703
1704     return s.str();
1705 }
1706
1707 string rfc1123Time()
1708 {
1709     char buffer[64];
1710     time_t now;
1711     time(&now);
1712     struct tm* now_gmt = gmtime(&now);
1713     string locale(setlocale(LC_TIME, NULL));
1714     setlocale(LC_TIME, "C"); // we want posix (aka "C") weekday/month strings
1715     strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt);
1716     setlocale(LC_TIME, locale.c_str());
1717     return string(buffer);
1718 }
1719
1720 static string HTTPReply(int nStatus, const string& strMsg)
1721 {
1722     if (nStatus == 401)
1723         return strprintf("HTTP/1.0 401 Authorization Required\r\n"
1724             "Date: %s\r\n"
1725             "Server: bitcoin-json-rpc/%s\r\n"
1726             "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
1727             "Content-Type: text/html\r\n"
1728             "Content-Length: 296\r\n"
1729             "\r\n"
1730             "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
1731             "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
1732             "<HTML>\r\n"
1733             "<HEAD>\r\n"
1734             "<TITLE>Error</TITLE>\r\n"
1735             "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
1736             "</HEAD>\r\n"
1737             "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
1738             "</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
1739     string strStatus;
1740          if (nStatus == 200) strStatus = "OK";
1741     else if (nStatus == 400) strStatus = "Bad Request";
1742     else if (nStatus == 403) strStatus = "Forbidden";
1743     else if (nStatus == 404) strStatus = "Not Found";
1744     else if (nStatus == 500) strStatus = "Internal Server Error";
1745     return strprintf(
1746             "HTTP/1.1 %d %s\r\n"
1747             "Date: %s\r\n"
1748             "Connection: close\r\n"
1749             "Content-Length: %d\r\n"
1750             "Content-Type: application/json\r\n"
1751             "Server: bitcoin-json-rpc/%s\r\n"
1752             "\r\n"
1753             "%s",
1754         nStatus,
1755         strStatus.c_str(),
1756         rfc1123Time().c_str(),
1757         strMsg.size(),
1758         FormatFullVersion().c_str(),
1759         strMsg.c_str());
1760 }
1761
1762 int ReadHTTPStatus(std::basic_istream<char>& stream)
1763 {
1764     string str;
1765     getline(stream, str);
1766     vector<string> vWords;
1767     boost::split(vWords, str, boost::is_any_of(" "));
1768     if (vWords.size() < 2)
1769         return 500;
1770     return atoi(vWords[1].c_str());
1771 }
1772
1773 int ReadHTTPHeader(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
1774 {
1775     int nLen = 0;
1776     loop
1777     {
1778         string str;
1779         std::getline(stream, str);
1780         if (str.empty() || str == "\r")
1781             break;
1782         string::size_type nColon = str.find(":");
1783         if (nColon != string::npos)
1784         {
1785             string strHeader = str.substr(0, nColon);
1786             boost::trim(strHeader);
1787             boost::to_lower(strHeader);
1788             string strValue = str.substr(nColon+1);
1789             boost::trim(strValue);
1790             mapHeadersRet[strHeader] = strValue;
1791             if (strHeader == "content-length")
1792                 nLen = atoi(strValue.c_str());
1793         }
1794     }
1795     return nLen;
1796 }
1797
1798 int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
1799 {
1800     mapHeadersRet.clear();
1801     strMessageRet = "";
1802
1803     // Read status
1804     int nStatus = ReadHTTPStatus(stream);
1805
1806     // Read header
1807     int nLen = ReadHTTPHeader(stream, mapHeadersRet);
1808     if (nLen < 0 || nLen > MAX_SIZE)
1809         return 500;
1810
1811     // Read message
1812     if (nLen > 0)
1813     {
1814         vector<char> vch(nLen);
1815         stream.read(&vch[0], nLen);
1816         strMessageRet = string(vch.begin(), vch.end());
1817     }
1818
1819     return nStatus;
1820 }
1821
1822 string EncodeBase64(string s)
1823 {
1824     BIO *b64, *bmem;
1825     BUF_MEM *bptr;
1826
1827     b64 = BIO_new(BIO_f_base64());
1828     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1829     bmem = BIO_new(BIO_s_mem());
1830     b64 = BIO_push(b64, bmem);
1831     BIO_write(b64, s.c_str(), s.size());
1832     BIO_flush(b64);
1833     BIO_get_mem_ptr(b64, &bptr);
1834
1835     string result(bptr->data, bptr->length);
1836     BIO_free_all(b64);
1837
1838     return result;
1839 }
1840
1841 string DecodeBase64(string s)
1842 {
1843     BIO *b64, *bmem;
1844
1845     char* buffer = static_cast<char*>(calloc(s.size(), sizeof(char)));
1846
1847     b64 = BIO_new(BIO_f_base64());
1848     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1849     bmem = BIO_new_mem_buf(const_cast<char*>(s.c_str()), s.size());
1850     bmem = BIO_push(b64, bmem);
1851     BIO_read(bmem, buffer, s.size());
1852     BIO_free_all(bmem);
1853
1854     string result(buffer);
1855     free(buffer);
1856     return result;
1857 }
1858
1859 bool HTTPAuthorized(map<string, string>& mapHeaders)
1860 {
1861     string strAuth = mapHeaders["authorization"];
1862     if (strAuth.substr(0,6) != "Basic ")
1863         return false;
1864     string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
1865     string strUserPass = DecodeBase64(strUserPass64);
1866     string::size_type nColon = strUserPass.find(":");
1867     if (nColon == string::npos)
1868         return false;
1869     string strUser = strUserPass.substr(0, nColon);
1870     string strPassword = strUserPass.substr(nColon+1);
1871     return (strUser == mapArgs["-rpcuser"] && strPassword == mapArgs["-rpcpassword"]);
1872 }
1873
1874 //
1875 // JSON-RPC protocol.  Bitcoin speaks version 1.0 for maximum compatibility,
1876 // but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
1877 // unspecified (HTTP errors and contents of 'error').
1878 //
1879 // 1.0 spec: http://json-rpc.org/wiki/specification
1880 // 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http
1881 // http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
1882 //
1883
1884 string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
1885 {
1886     Object request;
1887     request.push_back(Pair("method", strMethod));
1888     request.push_back(Pair("params", params));
1889     request.push_back(Pair("id", id));
1890     return write_string(Value(request), false) + "\n";
1891 }
1892
1893 string JSONRPCReply(const Value& result, const Value& error, const Value& id)
1894 {
1895     Object reply;
1896     if (error.type() != null_type)
1897         reply.push_back(Pair("result", Value::null));
1898     else
1899         reply.push_back(Pair("result", result));
1900     reply.push_back(Pair("error", error));
1901     reply.push_back(Pair("id", id));
1902     return write_string(Value(reply), false) + "\n";
1903 }
1904
1905 void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
1906 {
1907     // Send error reply from json-rpc error object
1908     int nStatus = 500;
1909     int code = find_value(objError, "code").get_int();
1910     if (code == -32600) nStatus = 400;
1911     else if (code == -32601) nStatus = 404;
1912     string strReply = JSONRPCReply(Value::null, objError, id);
1913     stream << HTTPReply(nStatus, strReply) << std::flush;
1914 }
1915
1916 bool ClientAllowed(const string& strAddress)
1917 {
1918     if (strAddress == asio::ip::address_v4::loopback().to_string())
1919         return true;
1920     const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
1921     BOOST_FOREACH(string strAllow, vAllow)
1922         if (WildcardMatch(strAddress, strAllow))
1923             return true;
1924     return false;
1925 }
1926
1927 #ifdef USE_SSL
1928 //
1929 // IOStream device that speaks SSL but can also speak non-SSL
1930 //
1931 class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
1932 public:
1933     SSLIOStreamDevice(SSLStream &streamIn, bool fUseSSLIn) : stream(streamIn)
1934     {
1935         fUseSSL = fUseSSLIn;
1936         fNeedHandshake = fUseSSLIn;
1937     }
1938
1939     void handshake(ssl::stream_base::handshake_type role)
1940     {
1941         if (!fNeedHandshake) return;
1942         fNeedHandshake = false;
1943         stream.handshake(role);
1944     }
1945     std::streamsize read(char* s, std::streamsize n)
1946     {
1947         handshake(ssl::stream_base::server); // HTTPS servers read first
1948         if (fUseSSL) return stream.read_some(asio::buffer(s, n));
1949         return stream.next_layer().read_some(asio::buffer(s, n));
1950     }
1951     std::streamsize write(const char* s, std::streamsize n)
1952     {
1953         handshake(ssl::stream_base::client); // HTTPS clients write first
1954         if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
1955         return asio::write(stream.next_layer(), asio::buffer(s, n));
1956     }
1957     bool connect(const std::string& server, const std::string& port)
1958     {
1959         ip::tcp::resolver resolver(stream.get_io_service());
1960         ip::tcp::resolver::query query(server.c_str(), port.c_str());
1961         ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
1962         ip::tcp::resolver::iterator end;
1963         boost::system::error_code error = asio::error::host_not_found;
1964         while (error && endpoint_iterator != end)
1965         {
1966             stream.lowest_layer().close();
1967             stream.lowest_layer().connect(*endpoint_iterator++, error);
1968         }
1969         if (error)
1970             return false;
1971         return true;
1972     }
1973
1974 private:
1975     bool fNeedHandshake;
1976     bool fUseSSL;
1977     SSLStream& stream;
1978 };
1979 #endif
1980
1981 void ThreadRPCServer(void* parg)
1982 {
1983     IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
1984     try
1985     {
1986         vnThreadsRunning[4]++;
1987         ThreadRPCServer2(parg);
1988         vnThreadsRunning[4]--;
1989     }
1990     catch (std::exception& e) {
1991         vnThreadsRunning[4]--;
1992         PrintException(&e, "ThreadRPCServer()");
1993     } catch (...) {
1994         vnThreadsRunning[4]--;
1995         PrintException(NULL, "ThreadRPCServer()");
1996     }
1997     printf("ThreadRPCServer exiting\n");
1998 }
1999
2000 void ThreadRPCServer2(void* parg)
2001 {
2002     printf("ThreadRPCServer started\n");
2003
2004     if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
2005     {
2006         string strWhatAmI = "To use bitcoind";
2007         if (mapArgs.count("-server"))
2008             strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
2009         else if (mapArgs.count("-daemon"))
2010             strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
2011         PrintConsole(
2012             _("Warning: %s, you must set rpcpassword=<password>\nin the configuration file: %s\n"
2013               "If the file does not exist, create it with owner-readable-only file permissions.\n"),
2014                 strWhatAmI.c_str(),
2015                 GetConfigFile().c_str());
2016         CreateThread(Shutdown, NULL);
2017         return;
2018     }
2019
2020     bool fUseSSL = GetBoolArg("-rpcssl");
2021     asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
2022
2023     asio::io_service io_service;
2024     ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
2025     ip::tcp::acceptor acceptor(io_service, endpoint);
2026
2027     acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
2028
2029 #ifdef USE_SSL
2030     ssl::context context(io_service, ssl::context::sslv23);
2031     if (fUseSSL)
2032     {
2033         context.set_options(ssl::context::no_sslv2);
2034         filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
2035         if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
2036         if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
2037         else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
2038         filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
2039         if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
2040         if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
2041         else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
2042
2043         string ciphers = GetArg("-rpcsslciphers",
2044                                          "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
2045         SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
2046     }
2047 #else
2048     if (fUseSSL)
2049         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2050 #endif
2051
2052     loop
2053     {
2054         // Accept connection
2055 #ifdef USE_SSL
2056         SSLStream sslStream(io_service, context);
2057         SSLIOStreamDevice d(sslStream, fUseSSL);
2058         iostreams::stream<SSLIOStreamDevice> stream(d);
2059 #else
2060         ip::tcp::iostream stream;
2061 #endif
2062
2063         ip::tcp::endpoint peer;
2064         vnThreadsRunning[4]--;
2065 #ifdef USE_SSL
2066         acceptor.accept(sslStream.lowest_layer(), peer);
2067 #else
2068         acceptor.accept(*stream.rdbuf(), peer);
2069 #endif
2070         vnThreadsRunning[4]++;
2071         if (fShutdown)
2072             return;
2073
2074         // Restrict callers by IP
2075         if (!ClientAllowed(peer.address().to_string()))
2076         {
2077             // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
2078             if (!fUseSSL)
2079                 stream << HTTPReply(403, "") << std::flush;
2080             continue;
2081         }
2082
2083         map<string, string> mapHeaders;
2084         string strRequest;
2085
2086         boost::thread api_caller(ReadHTTP, boost::ref(stream), boost::ref(mapHeaders), boost::ref(strRequest));
2087         if (!api_caller.timed_join(boost::posix_time::seconds(GetArg("-rpctimeout", 30))))
2088         {   // Timed out:
2089             acceptor.cancel();
2090             printf("ThreadRPCServer ReadHTTP timeout\n");
2091             continue;
2092         }
2093
2094         // Check authorization
2095         if (mapHeaders.count("authorization") == 0)
2096         {
2097             stream << HTTPReply(401, "") << std::flush;
2098             continue;
2099         }
2100         if (!HTTPAuthorized(mapHeaders))
2101         {
2102             // Deter brute-forcing short passwords
2103             if (mapArgs["-rpcpassword"].size() < 15)
2104                 Sleep(50);
2105
2106             stream << HTTPReply(401, "") << std::flush;
2107             printf("ThreadRPCServer incorrect password attempt\n");
2108             continue;
2109         }
2110
2111         Value id = Value::null;
2112         try
2113         {
2114             // Parse request
2115             Value valRequest;
2116             if (!read_string(strRequest, valRequest) || valRequest.type() != obj_type)
2117                 throw JSONRPCError(-32700, "Parse error");
2118             const Object& request = valRequest.get_obj();
2119
2120             // Parse id now so errors from here on will have the id
2121             id = find_value(request, "id");
2122
2123             // Parse method
2124             Value valMethod = find_value(request, "method");
2125             if (valMethod.type() == null_type)
2126                 throw JSONRPCError(-32600, "Missing method");
2127             if (valMethod.type() != str_type)
2128                 throw JSONRPCError(-32600, "Method must be a string");
2129             string strMethod = valMethod.get_str();
2130             if (strMethod != "getwork")
2131                 printf("ThreadRPCServer method=%s\n", strMethod.c_str());
2132
2133             // Parse params
2134             Value valParams = find_value(request, "params");
2135             Array params;
2136             if (valParams.type() == array_type)
2137                 params = valParams.get_array();
2138             else if (valParams.type() == null_type)
2139                 params = Array();
2140             else
2141                 throw JSONRPCError(-32600, "Params must be an array");
2142
2143             // Find method
2144             map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
2145             if (mi == mapCallTable.end())
2146                 throw JSONRPCError(-32601, "Method not found");
2147
2148             // Observe safe mode
2149             string strWarning = GetWarnings("rpc");
2150             if (strWarning != "" && !GetBoolArg("-disablesafemode") && !setAllowInSafeMode.count(strMethod))
2151                 throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
2152
2153             try
2154             {
2155                 // Execute
2156                 Value result;
2157                 CRITICAL_BLOCK(cs_main)
2158                 CRITICAL_BLOCK(pwalletMain->cs_wallet)
2159                     result = (*(*mi).second)(params, false);
2160
2161                 // Send reply
2162                 string strReply = JSONRPCReply(result, Value::null, id);
2163                 stream << HTTPReply(200, strReply) << std::flush;
2164             }
2165             catch (std::exception& e)
2166             {
2167                 ErrorReply(stream, JSONRPCError(-1, e.what()), id);
2168             }
2169         }
2170         catch (Object& objError)
2171         {
2172             ErrorReply(stream, objError, id);
2173         }
2174         catch (std::exception& e)
2175         {
2176             ErrorReply(stream, JSONRPCError(-32700, e.what()), id);
2177         }
2178     }
2179 }
2180
2181
2182
2183
2184 Object CallRPC(const string& strMethod, const Array& params)
2185 {
2186     if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
2187         throw runtime_error(strprintf(
2188             _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
2189               "If the file does not exist, create it with owner-readable-only file permissions."),
2190                 GetConfigFile().c_str()));
2191
2192     // Connect to localhost
2193     bool fUseSSL = GetBoolArg("-rpcssl");
2194 #ifdef USE_SSL
2195     asio::io_service io_service;
2196     ssl::context context(io_service, ssl::context::sslv23);
2197     context.set_options(ssl::context::no_sslv2);
2198     SSLStream sslStream(io_service, context);
2199     SSLIOStreamDevice d(sslStream, fUseSSL);
2200     iostreams::stream<SSLIOStreamDevice> stream(d);
2201     if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")))
2202         throw runtime_error("couldn't connect to server");
2203 #else
2204     if (fUseSSL)
2205         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2206
2207     ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"));
2208     if (stream.fail())
2209         throw runtime_error("couldn't connect to server");
2210 #endif
2211
2212
2213     // HTTP basic authentication
2214     string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
2215     map<string, string> mapRequestHeaders;
2216     mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
2217
2218     // Send request
2219     string strRequest = JSONRPCRequest(strMethod, params, 1);
2220     string strPost = HTTPPost(strRequest, mapRequestHeaders);
2221     stream << strPost << std::flush;
2222
2223     // Receive reply
2224     map<string, string> mapHeaders;
2225     string strReply;
2226     int nStatus = ReadHTTP(stream, mapHeaders, strReply);
2227     if (nStatus == 401)
2228         throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
2229     else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500)
2230         throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
2231     else if (strReply.empty())
2232         throw runtime_error("no response from server");
2233
2234     // Parse reply
2235     Value valReply;
2236     if (!read_string(strReply, valReply))
2237         throw runtime_error("couldn't parse reply from server");
2238     const Object& reply = valReply.get_obj();
2239     if (reply.empty())
2240         throw runtime_error("expected reply to have result, error and id properties");
2241
2242     return reply;
2243 }
2244
2245
2246
2247
2248 template<typename T>
2249 void ConvertTo(Value& value)
2250 {
2251     if (value.type() == str_type)
2252     {
2253         // reinterpret string as unquoted json value
2254         Value value2;
2255         if (!read_string(value.get_str(), value2))
2256             throw runtime_error("type mismatch");
2257         value = value2.get_value<T>();
2258     }
2259     else
2260     {
2261         value = value.get_value<T>();
2262     }
2263 }
2264
2265 int CommandLineRPC(int argc, char *argv[])
2266 {
2267     string strPrint;
2268     int nRet = 0;
2269     try
2270     {
2271         // Skip switches
2272         while (argc > 1 && IsSwitchChar(argv[1][0]))
2273         {
2274             argc--;
2275             argv++;
2276         }
2277
2278         // Method
2279         if (argc < 2)
2280             throw runtime_error("too few parameters");
2281         string strMethod = argv[1];
2282
2283         // Parameters default to strings
2284         Array params;
2285         for (int i = 2; i < argc; i++)
2286             params.push_back(argv[i]);
2287         int n = params.size();
2288
2289         //
2290         // Special case non-string parameter types
2291         //
2292         if (strMethod == "setgenerate"            && n > 0) ConvertTo<bool>(params[0]);
2293         if (strMethod == "setgenerate"            && n > 1) ConvertTo<boost::int64_t>(params[1]);
2294         if (strMethod == "sendtoaddress"          && n > 1) ConvertTo<double>(params[1]);
2295         if (strMethod == "settxfee"               && n > 0) ConvertTo<double>(params[0]);
2296         if (strMethod == "getamountreceived"      && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
2297         if (strMethod == "getreceivedbyaddress"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2298         if (strMethod == "getreceivedbyaccount"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2299         if (strMethod == "getreceivedbylabel"     && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
2300         if (strMethod == "getallreceived"         && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
2301         if (strMethod == "getallreceived"         && n > 1) ConvertTo<bool>(params[1]); // deprecated
2302         if (strMethod == "listreceivedbyaddress"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2303         if (strMethod == "listreceivedbyaddress"  && n > 1) ConvertTo<bool>(params[1]);
2304         if (strMethod == "listreceivedbyaccount"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2305         if (strMethod == "listreceivedbyaccount"  && n > 1) ConvertTo<bool>(params[1]);
2306         if (strMethod == "listreceivedbylabel"    && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
2307         if (strMethod == "listreceivedbylabel"    && n > 1) ConvertTo<bool>(params[1]); // deprecated
2308         if (strMethod == "getbalance"             && n > 1) ConvertTo<boost::int64_t>(params[1]);
2309         if (strMethod == "move"                   && n > 2) ConvertTo<double>(params[2]);
2310         if (strMethod == "move"                   && n > 3) ConvertTo<boost::int64_t>(params[3]);
2311         if (strMethod == "sendfrom"               && n > 2) ConvertTo<double>(params[2]);
2312         if (strMethod == "sendfrom"               && n > 3) ConvertTo<boost::int64_t>(params[3]);
2313         if (strMethod == "listtransactions"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2314         if (strMethod == "listtransactions"       && n > 2) ConvertTo<boost::int64_t>(params[2]);
2315         if (strMethod == "listaccounts"           && n > 0) ConvertTo<boost::int64_t>(params[0]);
2316         if (strMethod == "walletpassphrase"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2317         if (strMethod == "sendmany"               && n > 1)
2318         {
2319             string s = params[1].get_str();
2320             Value v;
2321             if (!read_string(s, v) || v.type() != obj_type)
2322                 throw runtime_error("type mismatch");
2323             params[1] = v.get_obj();
2324         }
2325         if (strMethod == "sendmany"                && n > 2) ConvertTo<boost::int64_t>(params[2]);
2326
2327         // Execute
2328         Object reply = CallRPC(strMethod, params);
2329
2330         // Parse reply
2331         const Value& result = find_value(reply, "result");
2332         const Value& error  = find_value(reply, "error");
2333
2334         if (error.type() != null_type)
2335         {
2336             // Error
2337             strPrint = "error: " + write_string(error, false);
2338             int code = find_value(error.get_obj(), "code").get_int();
2339             nRet = abs(code);
2340         }
2341         else
2342         {
2343             // Result
2344             if (result.type() == null_type)
2345                 strPrint = "";
2346             else if (result.type() == str_type)
2347                 strPrint = result.get_str();
2348             else
2349                 strPrint = write_string(result, true);
2350         }
2351     }
2352     catch (std::exception& e)
2353     {
2354         strPrint = string("error: ") + e.what();
2355         nRet = 87;
2356     }
2357     catch (...)
2358     {
2359         PrintException(NULL, "CommandLineRPC()");
2360     }
2361
2362     if (strPrint != "")
2363     {
2364 #if defined(__WXMSW__) && defined(GUI)
2365         // Windows GUI apps can't print to command line,
2366         // so settle for a message box yuck
2367         MyMessageBox(strPrint, "Bitcoin", wxOK);
2368 #else
2369         fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
2370 #endif
2371     }
2372     return nRet;
2373 }
2374
2375
2376
2377
2378 #ifdef TEST
2379 int main(int argc, char *argv[])
2380 {
2381 #ifdef _MSC_VER
2382     // Turn off microsoft heap dump noise
2383     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
2384     _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
2385 #endif
2386     setbuf(stdin, NULL);
2387     setbuf(stdout, NULL);
2388     setbuf(stderr, NULL);
2389
2390     try
2391     {
2392         if (argc >= 2 && string(argv[1]) == "-server")
2393         {
2394             printf("server ready\n");
2395             ThreadRPCServer(NULL);
2396         }
2397         else
2398         {
2399             return CommandLineRPC(argc, argv);
2400         }
2401     }
2402     catch (std::exception& e) {
2403         PrintException(&e, "main()");
2404     } catch (...) {
2405         PrintException(NULL, "main()");
2406     }
2407     return 0;
2408 }
2409 #endif