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