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