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