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