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