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