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