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