Remove wxWidgets
[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 string DecodeBase64(string s)
1834 {
1835     BIO *b64, *bmem;
1836
1837     char* buffer = static_cast<char*>(calloc(s.size(), sizeof(char)));
1838
1839     b64 = BIO_new(BIO_f_base64());
1840     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1841     bmem = BIO_new_mem_buf(const_cast<char*>(s.c_str()), s.size());
1842     bmem = BIO_push(b64, bmem);
1843     BIO_read(bmem, buffer, s.size());
1844     BIO_free_all(bmem);
1845
1846     string result(buffer);
1847     free(buffer);
1848     return result;
1849 }
1850
1851 bool HTTPAuthorized(map<string, string>& mapHeaders)
1852 {
1853     string strAuth = mapHeaders["authorization"];
1854     if (strAuth.substr(0,6) != "Basic ")
1855         return false;
1856     string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
1857     string strUserPass = DecodeBase64(strUserPass64);
1858     string::size_type nColon = strUserPass.find(":");
1859     if (nColon == string::npos)
1860         return false;
1861     string strUser = strUserPass.substr(0, nColon);
1862     string strPassword = strUserPass.substr(nColon+1);
1863     return (strUser == mapArgs["-rpcuser"] && strPassword == mapArgs["-rpcpassword"]);
1864 }
1865
1866 //
1867 // JSON-RPC protocol.  Bitcoin speaks version 1.0 for maximum compatibility,
1868 // but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
1869 // unspecified (HTTP errors and contents of 'error').
1870 //
1871 // 1.0 spec: http://json-rpc.org/wiki/specification
1872 // 1.2 spec: http://groups.google.com/group/json-rpc/web/json-rpc-over-http
1873 // http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
1874 //
1875
1876 string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
1877 {
1878     Object request;
1879     request.push_back(Pair("method", strMethod));
1880     request.push_back(Pair("params", params));
1881     request.push_back(Pair("id", id));
1882     return write_string(Value(request), false) + "\n";
1883 }
1884
1885 string JSONRPCReply(const Value& result, const Value& error, const Value& id)
1886 {
1887     Object reply;
1888     if (error.type() != null_type)
1889         reply.push_back(Pair("result", Value::null));
1890     else
1891         reply.push_back(Pair("result", result));
1892     reply.push_back(Pair("error", error));
1893     reply.push_back(Pair("id", id));
1894     return write_string(Value(reply), false) + "\n";
1895 }
1896
1897 void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
1898 {
1899     // Send error reply from json-rpc error object
1900     int nStatus = 500;
1901     int code = find_value(objError, "code").get_int();
1902     if (code == -32600) nStatus = 400;
1903     else if (code == -32601) nStatus = 404;
1904     string strReply = JSONRPCReply(Value::null, objError, id);
1905     stream << HTTPReply(nStatus, strReply) << std::flush;
1906 }
1907
1908 bool ClientAllowed(const string& strAddress)
1909 {
1910     if (strAddress == asio::ip::address_v4::loopback().to_string())
1911         return true;
1912     const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
1913     BOOST_FOREACH(string strAllow, vAllow)
1914         if (WildcardMatch(strAddress, strAllow))
1915             return true;
1916     return false;
1917 }
1918
1919 #ifdef USE_SSL
1920 //
1921 // IOStream device that speaks SSL but can also speak non-SSL
1922 //
1923 class SSLIOStreamDevice : public iostreams::device<iostreams::bidirectional> {
1924 public:
1925     SSLIOStreamDevice(SSLStream &streamIn, bool fUseSSLIn) : stream(streamIn)
1926     {
1927         fUseSSL = fUseSSLIn;
1928         fNeedHandshake = fUseSSLIn;
1929     }
1930
1931     void handshake(ssl::stream_base::handshake_type role)
1932     {
1933         if (!fNeedHandshake) return;
1934         fNeedHandshake = false;
1935         stream.handshake(role);
1936     }
1937     std::streamsize read(char* s, std::streamsize n)
1938     {
1939         handshake(ssl::stream_base::server); // HTTPS servers read first
1940         if (fUseSSL) return stream.read_some(asio::buffer(s, n));
1941         return stream.next_layer().read_some(asio::buffer(s, n));
1942     }
1943     std::streamsize write(const char* s, std::streamsize n)
1944     {
1945         handshake(ssl::stream_base::client); // HTTPS clients write first
1946         if (fUseSSL) return asio::write(stream, asio::buffer(s, n));
1947         return asio::write(stream.next_layer(), asio::buffer(s, n));
1948     }
1949     bool connect(const std::string& server, const std::string& port)
1950     {
1951         ip::tcp::resolver resolver(stream.get_io_service());
1952         ip::tcp::resolver::query query(server.c_str(), port.c_str());
1953         ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
1954         ip::tcp::resolver::iterator end;
1955         boost::system::error_code error = asio::error::host_not_found;
1956         while (error && endpoint_iterator != end)
1957         {
1958             stream.lowest_layer().close();
1959             stream.lowest_layer().connect(*endpoint_iterator++, error);
1960         }
1961         if (error)
1962             return false;
1963         return true;
1964     }
1965
1966 private:
1967     bool fNeedHandshake;
1968     bool fUseSSL;
1969     SSLStream& stream;
1970 };
1971 #endif
1972
1973 void ThreadRPCServer(void* parg)
1974 {
1975     IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
1976     try
1977     {
1978         vnThreadsRunning[4]++;
1979         ThreadRPCServer2(parg);
1980         vnThreadsRunning[4]--;
1981     }
1982     catch (std::exception& e) {
1983         vnThreadsRunning[4]--;
1984         PrintException(&e, "ThreadRPCServer()");
1985     } catch (...) {
1986         vnThreadsRunning[4]--;
1987         PrintException(NULL, "ThreadRPCServer()");
1988     }
1989     printf("ThreadRPCServer exiting\n");
1990 }
1991
1992 void ThreadRPCServer2(void* parg)
1993 {
1994     printf("ThreadRPCServer started\n");
1995
1996     if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
1997     {
1998         string strWhatAmI = "To use bitcoind";
1999         if (mapArgs.count("-server"))
2000             strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
2001         else if (mapArgs.count("-daemon"))
2002             strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
2003         PrintConsole(
2004             _("Warning: %s, you must set rpcpassword=<password>\nin the configuration file: %s\n"
2005               "If the file does not exist, create it with owner-readable-only file permissions.\n"),
2006                 strWhatAmI.c_str(),
2007                 GetConfigFile().c_str());
2008         CreateThread(Shutdown, NULL);
2009         return;
2010     }
2011
2012     bool fUseSSL = GetBoolArg("-rpcssl");
2013     asio::ip::address bindAddress = mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback();
2014
2015     asio::io_service io_service;
2016     ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
2017     ip::tcp::acceptor acceptor(io_service, endpoint);
2018
2019     acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
2020
2021 #ifdef USE_SSL
2022     ssl::context context(io_service, ssl::context::sslv23);
2023     if (fUseSSL)
2024     {
2025         context.set_options(ssl::context::no_sslv2);
2026         filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
2027         if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
2028         if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
2029         else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
2030         filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
2031         if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
2032         if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
2033         else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
2034
2035         string ciphers = GetArg("-rpcsslciphers",
2036                                          "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
2037         SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
2038     }
2039 #else
2040     if (fUseSSL)
2041         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2042 #endif
2043
2044     loop
2045     {
2046         // Accept connection
2047 #ifdef USE_SSL
2048         SSLStream sslStream(io_service, context);
2049         SSLIOStreamDevice d(sslStream, fUseSSL);
2050         iostreams::stream<SSLIOStreamDevice> stream(d);
2051 #else
2052         ip::tcp::iostream stream;
2053 #endif
2054
2055         ip::tcp::endpoint peer;
2056         vnThreadsRunning[4]--;
2057 #ifdef USE_SSL
2058         acceptor.accept(sslStream.lowest_layer(), peer);
2059 #else
2060         acceptor.accept(*stream.rdbuf(), peer);
2061 #endif
2062         vnThreadsRunning[4]++;
2063         if (fShutdown)
2064             return;
2065
2066         // Restrict callers by IP
2067         if (!ClientAllowed(peer.address().to_string()))
2068         {
2069             // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
2070             if (!fUseSSL)
2071                 stream << HTTPReply(403, "") << std::flush;
2072             continue;
2073         }
2074
2075         map<string, string> mapHeaders;
2076         string strRequest;
2077
2078         boost::thread api_caller(ReadHTTP, boost::ref(stream), boost::ref(mapHeaders), boost::ref(strRequest));
2079         if (!api_caller.timed_join(boost::posix_time::seconds(GetArg("-rpctimeout", 30))))
2080         {   // Timed out:
2081             acceptor.cancel();
2082             printf("ThreadRPCServer ReadHTTP timeout\n");
2083             continue;
2084         }
2085
2086         // Check authorization
2087         if (mapHeaders.count("authorization") == 0)
2088         {
2089             stream << HTTPReply(401, "") << std::flush;
2090             continue;
2091         }
2092         if (!HTTPAuthorized(mapHeaders))
2093         {
2094             // Deter brute-forcing short passwords
2095             if (mapArgs["-rpcpassword"].size() < 15)
2096                 Sleep(50);
2097
2098             stream << HTTPReply(401, "") << std::flush;
2099             printf("ThreadRPCServer incorrect password attempt\n");
2100             continue;
2101         }
2102
2103         Value id = Value::null;
2104         try
2105         {
2106             // Parse request
2107             Value valRequest;
2108             if (!read_string(strRequest, valRequest) || valRequest.type() != obj_type)
2109                 throw JSONRPCError(-32700, "Parse error");
2110             const Object& request = valRequest.get_obj();
2111
2112             // Parse id now so errors from here on will have the id
2113             id = find_value(request, "id");
2114
2115             // Parse method
2116             Value valMethod = find_value(request, "method");
2117             if (valMethod.type() == null_type)
2118                 throw JSONRPCError(-32600, "Missing method");
2119             if (valMethod.type() != str_type)
2120                 throw JSONRPCError(-32600, "Method must be a string");
2121             string strMethod = valMethod.get_str();
2122             if (strMethod != "getwork")
2123                 printf("ThreadRPCServer method=%s\n", strMethod.c_str());
2124
2125             // Parse params
2126             Value valParams = find_value(request, "params");
2127             Array params;
2128             if (valParams.type() == array_type)
2129                 params = valParams.get_array();
2130             else if (valParams.type() == null_type)
2131                 params = Array();
2132             else
2133                 throw JSONRPCError(-32600, "Params must be an array");
2134
2135             // Find method
2136             map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
2137             if (mi == mapCallTable.end())
2138                 throw JSONRPCError(-32601, "Method not found");
2139
2140             // Observe safe mode
2141             string strWarning = GetWarnings("rpc");
2142             if (strWarning != "" && !GetBoolArg("-disablesafemode") && !setAllowInSafeMode.count(strMethod))
2143                 throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
2144
2145             try
2146             {
2147                 // Execute
2148                 Value result;
2149                 CRITICAL_BLOCK(cs_main)
2150                 CRITICAL_BLOCK(pwalletMain->cs_wallet)
2151                     result = (*(*mi).second)(params, false);
2152
2153                 // Send reply
2154                 string strReply = JSONRPCReply(result, Value::null, id);
2155                 stream << HTTPReply(200, strReply) << std::flush;
2156             }
2157             catch (std::exception& e)
2158             {
2159                 ErrorReply(stream, JSONRPCError(-1, e.what()), id);
2160             }
2161         }
2162         catch (Object& objError)
2163         {
2164             ErrorReply(stream, objError, id);
2165         }
2166         catch (std::exception& e)
2167         {
2168             ErrorReply(stream, JSONRPCError(-32700, e.what()), id);
2169         }
2170     }
2171 }
2172
2173
2174
2175
2176 Object CallRPC(const string& strMethod, const Array& params)
2177 {
2178     if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
2179         throw runtime_error(strprintf(
2180             _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
2181               "If the file does not exist, create it with owner-readable-only file permissions."),
2182                 GetConfigFile().c_str()));
2183
2184     // Connect to localhost
2185     bool fUseSSL = GetBoolArg("-rpcssl");
2186 #ifdef USE_SSL
2187     asio::io_service io_service;
2188     ssl::context context(io_service, ssl::context::sslv23);
2189     context.set_options(ssl::context::no_sslv2);
2190     SSLStream sslStream(io_service, context);
2191     SSLIOStreamDevice d(sslStream, fUseSSL);
2192     iostreams::stream<SSLIOStreamDevice> stream(d);
2193     if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332")))
2194         throw runtime_error("couldn't connect to server");
2195 #else
2196     if (fUseSSL)
2197         throw runtime_error("-rpcssl=1, but bitcoin compiled without full openssl libraries.");
2198
2199     ip::tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", "8332"));
2200     if (stream.fail())
2201         throw runtime_error("couldn't connect to server");
2202 #endif
2203
2204
2205     // HTTP basic authentication
2206     string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
2207     map<string, string> mapRequestHeaders;
2208     mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
2209
2210     // Send request
2211     string strRequest = JSONRPCRequest(strMethod, params, 1);
2212     string strPost = HTTPPost(strRequest, mapRequestHeaders);
2213     stream << strPost << std::flush;
2214
2215     // Receive reply
2216     map<string, string> mapHeaders;
2217     string strReply;
2218     int nStatus = ReadHTTP(stream, mapHeaders, strReply);
2219     if (nStatus == 401)
2220         throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
2221     else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500)
2222         throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
2223     else if (strReply.empty())
2224         throw runtime_error("no response from server");
2225
2226     // Parse reply
2227     Value valReply;
2228     if (!read_string(strReply, valReply))
2229         throw runtime_error("couldn't parse reply from server");
2230     const Object& reply = valReply.get_obj();
2231     if (reply.empty())
2232         throw runtime_error("expected reply to have result, error and id properties");
2233
2234     return reply;
2235 }
2236
2237
2238
2239
2240 template<typename T>
2241 void ConvertTo(Value& value)
2242 {
2243     if (value.type() == str_type)
2244     {
2245         // reinterpret string as unquoted json value
2246         Value value2;
2247         if (!read_string(value.get_str(), value2))
2248             throw runtime_error("type mismatch");
2249         value = value2.get_value<T>();
2250     }
2251     else
2252     {
2253         value = value.get_value<T>();
2254     }
2255 }
2256
2257 int CommandLineRPC(int argc, char *argv[])
2258 {
2259     string strPrint;
2260     int nRet = 0;
2261     try
2262     {
2263         // Skip switches
2264         while (argc > 1 && IsSwitchChar(argv[1][0]))
2265         {
2266             argc--;
2267             argv++;
2268         }
2269
2270         // Method
2271         if (argc < 2)
2272             throw runtime_error("too few parameters");
2273         string strMethod = argv[1];
2274
2275         // Parameters default to strings
2276         Array params;
2277         for (int i = 2; i < argc; i++)
2278             params.push_back(argv[i]);
2279         int n = params.size();
2280
2281         //
2282         // Special case non-string parameter types
2283         //
2284         if (strMethod == "setgenerate"            && n > 0) ConvertTo<bool>(params[0]);
2285         if (strMethod == "setgenerate"            && n > 1) ConvertTo<boost::int64_t>(params[1]);
2286         if (strMethod == "sendtoaddress"          && n > 1) ConvertTo<double>(params[1]);
2287         if (strMethod == "settxfee"               && n > 0) ConvertTo<double>(params[0]);
2288         if (strMethod == "getamountreceived"      && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
2289         if (strMethod == "getreceivedbyaddress"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2290         if (strMethod == "getreceivedbyaccount"   && n > 1) ConvertTo<boost::int64_t>(params[1]);
2291         if (strMethod == "getreceivedbylabel"     && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated
2292         if (strMethod == "getallreceived"         && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
2293         if (strMethod == "getallreceived"         && n > 1) ConvertTo<bool>(params[1]); // deprecated
2294         if (strMethod == "listreceivedbyaddress"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2295         if (strMethod == "listreceivedbyaddress"  && n > 1) ConvertTo<bool>(params[1]);
2296         if (strMethod == "listreceivedbyaccount"  && n > 0) ConvertTo<boost::int64_t>(params[0]);
2297         if (strMethod == "listreceivedbyaccount"  && n > 1) ConvertTo<bool>(params[1]);
2298         if (strMethod == "listreceivedbylabel"    && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated
2299         if (strMethod == "listreceivedbylabel"    && n > 1) ConvertTo<bool>(params[1]); // deprecated
2300         if (strMethod == "getbalance"             && n > 1) ConvertTo<boost::int64_t>(params[1]);
2301         if (strMethod == "move"                   && n > 2) ConvertTo<double>(params[2]);
2302         if (strMethod == "move"                   && n > 3) ConvertTo<boost::int64_t>(params[3]);
2303         if (strMethod == "sendfrom"               && n > 2) ConvertTo<double>(params[2]);
2304         if (strMethod == "sendfrom"               && n > 3) ConvertTo<boost::int64_t>(params[3]);
2305         if (strMethod == "listtransactions"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2306         if (strMethod == "listtransactions"       && n > 2) ConvertTo<boost::int64_t>(params[2]);
2307         if (strMethod == "listaccounts"           && n > 0) ConvertTo<boost::int64_t>(params[0]);
2308         if (strMethod == "walletpassphrase"       && n > 1) ConvertTo<boost::int64_t>(params[1]);
2309         if (strMethod == "sendmany"               && n > 1)
2310         {
2311             string s = params[1].get_str();
2312             Value v;
2313             if (!read_string(s, v) || v.type() != obj_type)
2314                 throw runtime_error("type mismatch");
2315             params[1] = v.get_obj();
2316         }
2317         if (strMethod == "sendmany"                && n > 2) ConvertTo<boost::int64_t>(params[2]);
2318
2319         // Execute
2320         Object reply = CallRPC(strMethod, params);
2321
2322         // Parse reply
2323         const Value& result = find_value(reply, "result");
2324         const Value& error  = find_value(reply, "error");
2325
2326         if (error.type() != null_type)
2327         {
2328             // Error
2329             strPrint = "error: " + write_string(error, false);
2330             int code = find_value(error.get_obj(), "code").get_int();
2331             nRet = abs(code);
2332         }
2333         else
2334         {
2335             // Result
2336             if (result.type() == null_type)
2337                 strPrint = "";
2338             else if (result.type() == str_type)
2339                 strPrint = result.get_str();
2340             else
2341                 strPrint = write_string(result, true);
2342         }
2343     }
2344     catch (std::exception& e)
2345     {
2346         strPrint = string("error: ") + e.what();
2347         nRet = 87;
2348     }
2349     catch (...)
2350     {
2351         PrintException(NULL, "CommandLineRPC()");
2352     }
2353
2354     if (strPrint != "")
2355     {
2356         fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
2357     }
2358     return nRet;
2359 }
2360
2361
2362
2363
2364 #ifdef TEST
2365 int main(int argc, char *argv[])
2366 {
2367 #ifdef _MSC_VER
2368     // Turn off microsoft heap dump noise
2369     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
2370     _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
2371 #endif
2372     setbuf(stdin, NULL);
2373     setbuf(stdout, NULL);
2374     setbuf(stderr, NULL);
2375
2376     try
2377     {
2378         if (argc >= 2 && string(argv[1]) == "-server")
2379         {
2380             printf("server ready\n");
2381             ThreadRPCServer(NULL);
2382         }
2383         else
2384         {
2385             return CommandLineRPC(argc, argv);
2386         }
2387     }
2388     catch (std::exception& e) {
2389         PrintException(&e, "main()");
2390     } catch (...) {
2391         PrintException(NULL, "main()");
2392     }
2393     return 0;
2394 }
2395 #endif