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