]> Git Repo - VerusCoin.git/blob - src/rpcblockchain.cpp
test
[VerusCoin.git] / src / rpcblockchain.cpp
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "checkpoints.h"
7 #include "consensus/validation.h"
8 #include "main.h"
9 #include "primitives/transaction.h"
10 #include "rpcserver.h"
11 #include "sync.h"
12 #include "util.h"
13
14 #include <stdint.h>
15
16 #include "json/json_spirit_value.h"
17
18 using namespace json_spirit;
19 using namespace std;
20
21 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
22 void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
23
24 double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
25 {
26     // Floating point number that is a multiple of the minimum difficulty,
27     // minimum difficulty = 1.0.
28     if (blockindex == NULL)
29     {
30         if (chainActive.Tip() == NULL)
31             return 1.0;
32         else
33             blockindex = chainActive.Tip();
34     }
35
36     uint32_t bits;
37     if (networkDifficulty) {
38         bits = GetNextWorkRequired(blockindex, nullptr, Params().GetConsensus());
39     } else {
40         bits = blockindex->nBits;
41     }
42
43     uint32_t powLimit =
44         UintToArith256(Params().GetConsensus().powLimit).GetCompact();
45     int nShift = (bits >> 24) & 0xff;
46     int nShiftAmount = (powLimit >> 24) & 0xff;
47
48     double dDiff =
49         (double)(powLimit & 0x00ffffff) / 
50         (double)(bits & 0x00ffffff);
51
52     while (nShift < nShiftAmount)
53     {
54         dDiff *= 256.0;
55         nShift++;
56     }
57     while (nShift > nShiftAmount)
58     {
59         dDiff /= 256.0;
60         nShift--;
61     }
62
63     return dDiff;
64 }
65
66 double GetDifficulty(const CBlockIndex* blockindex)
67 {
68     return GetDifficultyINTERNAL(blockindex, false);
69 }
70
71 double GetNetworkDifficulty(const CBlockIndex* blockindex)
72 {
73     return GetDifficultyINTERNAL(blockindex, true);
74 }
75
76
77 Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
78 {
79     Object result;
80     result.push_back(Pair("hash", block.GetHash().GetHex()));
81     int confirmations = -1;
82     // Only report confirmations if the block is on the main chain
83     if (chainActive.Contains(blockindex))
84         confirmations = chainActive.Height() - blockindex->nHeight + 1;
85     result.push_back(Pair("confirmations", confirmations));
86     result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
87     result.push_back(Pair("height", blockindex->nHeight));
88     result.push_back(Pair("version", block.nVersion));
89     result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
90     Array txs;
91     BOOST_FOREACH(const CTransaction&tx, block.vtx)
92     {
93         if(txDetails)
94         {
95             Object objTx;
96             TxToJSON(tx, uint256(), objTx);
97             txs.push_back(objTx);
98         }
99         else
100             txs.push_back(tx.GetHash().GetHex());
101     }
102     result.push_back(Pair("tx", txs));
103     result.push_back(Pair("time", block.GetBlockTime()));
104     result.push_back(Pair("nonce", block.nNonce.GetHex()));
105     result.push_back(Pair("solution", HexStr(block.nSolution)));
106     result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
107     result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
108     result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
109
110     if (blockindex->pprev)
111         result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
112     CBlockIndex *pnext = chainActive.Next(blockindex);
113     if (pnext)
114         result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
115     return result;
116 }
117
118
119 Value getblockcount(const Array& params, bool fHelp)
120 {
121     if (fHelp || params.size() != 0)
122         throw runtime_error(
123             "getblockcount\n"
124             "\nReturns the number of blocks in the longest block chain.\n"
125             "\nResult:\n"
126             "n    (numeric) The current block count\n"
127             "\nExamples:\n"
128             + HelpExampleCli("getblockcount", "")
129             + HelpExampleRpc("getblockcount", "")
130         );
131
132     LOCK(cs_main);
133     return chainActive.Height();
134 }
135
136 Value getbestblockhash(const Array& params, bool fHelp)
137 {
138     if (fHelp || params.size() != 0)
139         throw runtime_error(
140             "getbestblockhash\n"
141             "\nReturns the hash of the best (tip) block in the longest block chain.\n"
142             "\nResult\n"
143             "\"hex\"      (string) the block hash hex encoded\n"
144             "\nExamples\n"
145             + HelpExampleCli("getbestblockhash", "")
146             + HelpExampleRpc("getbestblockhash", "")
147         );
148
149     LOCK(cs_main);
150     return chainActive.Tip()->GetBlockHash().GetHex();
151 }
152
153 Value getdifficulty(const Array& params, bool fHelp)
154 {
155     if (fHelp || params.size() != 0)
156         throw runtime_error(
157             "getdifficulty\n"
158             "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
159             "\nResult:\n"
160             "n.nnn       (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
161             "\nExamples:\n"
162             + HelpExampleCli("getdifficulty", "")
163             + HelpExampleRpc("getdifficulty", "")
164         );
165
166     LOCK(cs_main);
167     return GetNetworkDifficulty();
168 }
169
170
171 Value getrawmempool(const Array& params, bool fHelp)
172 {
173     if (fHelp || params.size() > 1)
174         throw runtime_error(
175             "getrawmempool ( verbose )\n"
176             "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
177             "\nArguments:\n"
178             "1. verbose           (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
179             "\nResult: (for verbose = false):\n"
180             "[                     (json array of string)\n"
181             "  \"transactionid\"     (string) The transaction id\n"
182             "  ,...\n"
183             "]\n"
184             "\nResult: (for verbose = true):\n"
185             "{                           (json object)\n"
186             "  \"transactionid\" : {       (json object)\n"
187             "    \"size\" : n,             (numeric) transaction size in bytes\n"
188             "    \"fee\" : n,              (numeric) transaction fee in bitcoins\n"
189             "    \"time\" : n,             (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
190             "    \"height\" : n,           (numeric) block height when transaction entered pool\n"
191             "    \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
192             "    \"currentpriority\" : n,  (numeric) transaction priority now\n"
193             "    \"depends\" : [           (array) unconfirmed transactions used as inputs for this transaction\n"
194             "        \"transactionid\",    (string) parent transaction id\n"
195             "       ... ]\n"
196             "  }, ...\n"
197             "}\n"
198             "\nExamples\n"
199             + HelpExampleCli("getrawmempool", "true")
200             + HelpExampleRpc("getrawmempool", "true")
201         );
202
203     LOCK(cs_main);
204
205     bool fVerbose = false;
206     if (params.size() > 0)
207         fVerbose = params[0].get_bool();
208
209     if (fVerbose)
210     {
211         LOCK(mempool.cs);
212         Object o;
213         BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
214         {
215             const uint256& hash = entry.first;
216             const CTxMemPoolEntry& e = entry.second;
217             Object info;
218             info.push_back(Pair("size", (int)e.GetTxSize()));
219             info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
220             info.push_back(Pair("time", e.GetTime()));
221             info.push_back(Pair("height", (int)e.GetHeight()));
222             info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
223             info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
224             const CTransaction& tx = e.GetTx();
225             set<string> setDepends;
226             BOOST_FOREACH(const CTxIn& txin, tx.vin)
227             {
228                 if (mempool.exists(txin.prevout.hash))
229                     setDepends.insert(txin.prevout.hash.ToString());
230             }
231             Array depends(setDepends.begin(), setDepends.end());
232             info.push_back(Pair("depends", depends));
233             o.push_back(Pair(hash.ToString(), info));
234         }
235         return o;
236     }
237     else
238     {
239         vector<uint256> vtxid;
240         mempool.queryHashes(vtxid);
241
242         Array a;
243         BOOST_FOREACH(const uint256& hash, vtxid)
244             a.push_back(hash.ToString());
245
246         return a;
247     }
248 }
249
250 Value getblockhash(const Array& params, bool fHelp)
251 {
252     if (fHelp || params.size() != 1)
253         throw runtime_error(
254             "getblockhash index\n"
255             "\nReturns hash of block in best-block-chain at index provided.\n"
256             "\nArguments:\n"
257             "1. index         (numeric, required) The block index\n"
258             "\nResult:\n"
259             "\"hash\"         (string) The block hash\n"
260             "\nExamples:\n"
261             + HelpExampleCli("getblockhash", "1000")
262             + HelpExampleRpc("getblockhash", "1000")
263         );
264
265     LOCK(cs_main);
266
267     int nHeight = params[0].get_int();
268     if (nHeight < 0 || nHeight > chainActive.Height())
269         throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
270
271     CBlockIndex* pblockindex = chainActive[nHeight];
272     return pblockindex->GetBlockHash().GetHex();
273 }
274
275 Value getblock(const Array& params, bool fHelp)
276 {
277     if (fHelp || params.size() < 1 || params.size() > 2)
278         throw runtime_error(
279             "getblock \"hash\" ( verbose )\n"
280             "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
281             "If verbose is true, returns an Object with information about block <hash>.\n"
282             "\nArguments:\n"
283             "1. \"hash\"          (string, required) The block hash\n"
284             "2. verbose           (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
285             "\nResult (for verbose = true):\n"
286             "{\n"
287             "  \"hash\" : \"hash\",     (string) the block hash (same as provided)\n"
288             "  \"confirmations\" : n,   (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
289             "  \"size\" : n,            (numeric) The block size\n"
290             "  \"height\" : n,          (numeric) The block height or index\n"
291             "  \"version\" : n,         (numeric) The block version\n"
292             "  \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
293             "  \"tx\" : [               (array of string) The transaction ids\n"
294             "     \"transactionid\"     (string) The transaction id\n"
295             "     ,...\n"
296             "  ],\n"
297             "  \"time\" : ttt,          (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
298             "  \"nonce\" : n,           (numeric) The nonce\n"
299             "  \"bits\" : \"1d00ffff\", (string) The bits\n"
300             "  \"difficulty\" : x.xxx,  (numeric) The difficulty\n"
301             "  \"previousblockhash\" : \"hash\",  (string) The hash of the previous block\n"
302             "  \"nextblockhash\" : \"hash\"       (string) The hash of the next block\n"
303             "}\n"
304             "\nResult (for verbose=false):\n"
305             "\"data\"             (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
306             "\nExamples:\n"
307             + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
308             + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
309         );
310
311     LOCK(cs_main);
312
313     std::string strHash = params[0].get_str();
314     uint256 hash(uint256S(strHash));
315
316     bool fVerbose = true;
317     if (params.size() > 1)
318         fVerbose = params[1].get_bool();
319
320     if (mapBlockIndex.count(hash) == 0)
321         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
322
323     CBlock block;
324     CBlockIndex* pblockindex = mapBlockIndex[hash];
325
326     if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
327         throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
328
329     if(!ReadBlockFromDisk(block, pblockindex))
330         throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
331
332     if (!fVerbose)
333     {
334         CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
335         ssBlock << block;
336         std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
337         return strHex;
338     }
339
340     return blockToJSON(block, pblockindex);
341 }
342
343 Value gettxoutsetinfo(const Array& params, bool fHelp)
344 {
345     if (fHelp || params.size() != 0)
346         throw runtime_error(
347             "gettxoutsetinfo\n"
348             "\nReturns statistics about the unspent transaction output set.\n"
349             "Note this call may take some time.\n"
350             "\nResult:\n"
351             "{\n"
352             "  \"height\":n,     (numeric) The current block height (index)\n"
353             "  \"bestblock\": \"hex\",   (string) the best block hash hex\n"
354             "  \"transactions\": n,      (numeric) The number of transactions\n"
355             "  \"txouts\": n,            (numeric) The number of output transactions\n"
356             "  \"bytes_serialized\": n,  (numeric) The serialized size\n"
357             "  \"hash_serialized\": \"hash\",   (string) The serialized hash\n"
358             "  \"total_amount\": x.xxx          (numeric) The total amount\n"
359             "}\n"
360             "\nExamples:\n"
361             + HelpExampleCli("gettxoutsetinfo", "")
362             + HelpExampleRpc("gettxoutsetinfo", "")
363         );
364
365     LOCK(cs_main);
366
367     Object ret;
368
369     CCoinsStats stats;
370     FlushStateToDisk();
371     if (pcoinsTip->GetStats(stats)) {
372         ret.push_back(Pair("height", (int64_t)stats.nHeight));
373         ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
374         ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
375         ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
376         ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
377         ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
378         ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
379     }
380     return ret;
381 }
382
383 uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
384 uint32_t komodo_txtime(uint256 hash);
385 uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume);
386 int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel);
387 int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height);
388 char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len);
389 uint32_t komodo_interest_args(int32_t *txheightp,uint32_t *tiptimep,uint64_t *valuep,uint256 hash,int32_t n);
390 int32_t komodo_minerids(uint8_t *minerids,int32_t height);
391
392 Value minerids(const Array& params, bool fHelp)
393 {
394     Object ret; Array a; uint8_t minerids[1000],pubkeys[64][33]; int32_t i,j,n,numnotaries,tally[65];
395     if ( fHelp || params.size() != 1 )
396         throw runtime_error("minerids needs height\n");
397     LOCK(cs_main);
398     int32_t height = atoi(params[0].get_str().c_str());
399     if ( height <= 0 )
400         height = chainActive.Tip()->nHeight;
401     if ( (n= komodo_minerids(minerids,height)) > 0 )
402     {
403         memset(tally,0,sizeof(tally));
404         numnotaries = komodo_notaries(pubkeys,height);
405         if ( numnotaries > 0 )
406         {
407             for (i=0; i<n; i++)
408             {
409                 if ( minerids[i] >= numnotaries )
410                     tally[64]++;
411                 else tally[minerids[i]]++;
412             }
413             for (i=0; i<64; i++)
414             {
415                 Object item; std::string hex; char *hexstr;
416                 hex.resize(66);
417                 hexstr = (char *)hex.data();
418                 for (j=0; j<33; j++)
419                     sprintf(&hexstr[j*2],"%02x",pubkeys[i][j]);
420                 item.push_back(Pair("notaryid", i));
421                 item.push_back(Pair("pubkey", hex));
422                 item.push_back(Pair("blocks", tally[i]));
423                 a.push_back(item);
424             }
425             Object item;
426             item.push_back(Pair("pubkey", (char *)"external miners"));
427             item.push_back(Pair("blocks", tally[64]));
428             a.push_back(item);
429         }
430         ret.push_back(Pair("mined", a));
431     } else ret.push_back(Pair("error", (char *)"couldnt extract minerids"));
432     return ret;
433 }
434
435 Value notaries(const Array& params, bool fHelp)
436 {
437     Array a; Object ret; int32_t i,j,n,m; char *hexstr;  uint8_t pubkeys[64][33]; char btcaddr[64],kmdaddr[64],*ptr;
438     if ( fHelp || params.size() != 1 )
439         throw runtime_error("notaries height\n");
440     LOCK(cs_main);
441     int32_t height = atoi(params[0].get_str().c_str());
442     if ( height < 0 )
443         height = 0;
444     //fprintf(stderr,"notaries as of height.%d\n",height);
445     //if ( height > chainActive.Height()+20000 )
446     //    throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
447     //else
448     {
449         if ( (n= komodo_notaries(pubkeys,height)) > 0 )
450         {
451             for (i=0; i<n; i++)
452             {
453                 Object item;
454                 std::string btcaddress,kmdaddress,hex;
455                 hex.resize(66);
456                 hexstr = (char *)hex.data();
457                 for (j=0; j<33; j++)
458                     sprintf(&hexstr[j*2],"%02x",pubkeys[i][j]);
459                 item.push_back(Pair("pubkey", hex));
460
461                 bitcoin_address(btcaddr,0,pubkeys[i],33);
462                 m = (int32_t)strlen(btcaddr);
463                 btcaddress.resize(m);
464                 ptr = (char *)btcaddress.data();
465                 memcpy(ptr,btcaddr,m);
466                 item.push_back(Pair("BTCaddress", btcaddress));
467
468                 bitcoin_address(kmdaddr,60,pubkeys[i],33);
469                 m = (int32_t)strlen(kmdaddr);
470                 kmdaddress.resize(m);
471                 ptr = (char *)kmdaddress.data();
472                 memcpy(ptr,kmdaddr,m);
473                 item.push_back(Pair("KMDaddress", kmdaddress));
474                 a.push_back(item);
475             }
476         }
477         ret.push_back(Pair("notaries", a));
478         ret.push_back(Pair("numnotaries", n));
479     }
480     return ret;
481 }
482
483 int32_t komodo_pending_withdraws(char *opretstr);
484
485 Value paxpending(const Array& params, bool fHelp)
486 {
487     Object ret; char opretbuf[10000*2]; int32_t opretlen;
488     if ( fHelp || params.size() != 0 )
489         throw runtime_error("paxpending needs no args\n");
490     LOCK(cs_main);
491     if ( (opretlen= komodo_pending_withdraws(opretbuf)) > 0 )
492         ret.push_back(Pair("withdraws", opretbuf));
493     else ret.push_back(Pair("withdraws", (char *)""));
494     return ret;
495 }
496
497 Value paxprice(const Array& params, bool fHelp)
498 {
499     if ( fHelp || params.size() < 3 || params.size() > 4 )
500         throw runtime_error("paxprice \"base\" \"rel\" height amount\n");
501     LOCK(cs_main);
502     Object ret; uint64_t basevolume=0,relvolume,seed;
503     std::string base = params[0].get_str();
504     std::string rel = params[1].get_str();
505     int32_t height = atoi(params[2].get_str().c_str());
506     if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 )
507         basevolume = COIN;
508     relvolume = komodo_paxprice(&seed,height,(char *)base.c_str(),(char *)rel.c_str(),basevolume);
509     ret.push_back(Pair("base", base));
510     ret.push_back(Pair("rel", rel));
511     ret.push_back(Pair("height", height));
512     char seedstr[32];
513     sprintf(seedstr,"%llu",(long long)seed);
514     ret.push_back(Pair("seed", seedstr));
515     if ( height < 0 || height > chainActive.Height() )
516         throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
517     else
518     {
519         CBlockIndex *pblockindex = chainActive[height];
520         ret.push_back(Pair("timestamp", (int64_t)pblockindex->nTime));
521         if ( basevolume != 0 && relvolume != 0 )
522         {
523             ret.push_back(Pair("price",((double)relvolume / (double)basevolume)));
524             ret.push_back(Pair("invprice",((double)basevolume / (double)relvolume)));
525             ret.push_back(Pair("basevolume", ValueFromAmount(basevolume)));
526             ret.push_back(Pair("relvolume", ValueFromAmount(relvolume)));
527         } else ret.push_back(Pair("error", "overflow or error in one or more of parameters"));
528     }
529     return ret;
530 }
531
532 Value paxprices(const Array& params, bool fHelp)
533 {
534     if ( fHelp || params.size() != 3 )
535         throw runtime_error("paxprices \"base\" \"rel\" maxsamples\n");
536     LOCK(cs_main);
537     Object ret; uint64_t relvolume,prices[4096]; uint32_t i,n; int32_t heights[sizeof(prices)/sizeof(*prices)];
538     std::string base = params[0].get_str();
539     std::string rel = params[1].get_str();
540     int32_t maxsamples = atoi(params[2].get_str().c_str());
541     if ( maxsamples < 1 )
542         maxsamples = 1;
543     else if ( maxsamples > sizeof(heights)/sizeof(*heights) )
544         maxsamples = sizeof(heights)/sizeof(*heights);
545     ret.push_back(Pair("base", base));
546     ret.push_back(Pair("rel", rel));
547     n = komodo_paxprices(heights,prices,maxsamples,(char *)base.c_str(),(char *)rel.c_str());
548     Array a;
549     for (i=0; i<n; i++)
550     {
551         Object item;
552         if ( heights[i] < 0 || heights[i] > chainActive.Height() )
553             throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
554         else
555         {
556             CBlockIndex *pblockindex = chainActive[heights[i]];
557             
558             item.push_back(Pair("t", (int64_t)pblockindex->nTime));
559             item.push_back(Pair("p", (double)prices[i] / COIN));
560             a.push_back(item);
561         }
562     }
563     ret.push_back(Pair("array", a));
564     return ret;
565 }
566
567 uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue);
568
569 Value gettxout(const Array& params, bool fHelp)
570 {
571     if (fHelp || params.size() < 2 || params.size() > 3)
572         throw runtime_error(
573             "gettxout \"txid\" n ( includemempool )\n"
574             "\nReturns details about an unspent transaction output.\n"
575             "\nArguments:\n"
576             "1. \"txid\"       (string, required) The transaction id\n"
577             "2. n              (numeric, required) vout value\n"
578             "3. includemempool  (boolean, optional) Whether to included the mem pool\n"
579             "\nResult:\n"
580             "{\n"
581             "  \"bestblock\" : \"hash\",    (string) the block hash\n"
582             "  \"confirmations\" : n,       (numeric) The number of confirmations\n"
583             "  \"value\" : x.xxx,           (numeric) The transaction value in btc\n"
584             "  \"scriptPubKey\" : {         (json object)\n"
585             "     \"asm\" : \"code\",       (string) \n"
586             "     \"hex\" : \"hex\",        (string) \n"
587             "     \"reqSigs\" : n,          (numeric) Number of required signatures\n"
588             "     \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
589             "     \"addresses\" : [          (array of string) array of bitcoin addresses\n"
590             "        \"bitcoinaddress\"     (string) bitcoin address\n"
591             "        ,...\n"
592             "     ]\n"
593             "  },\n"
594             "  \"version\" : n,            (numeric) The version\n"
595             "  \"coinbase\" : true|false   (boolean) Coinbase or not\n"
596             "}\n"
597
598             "\nExamples:\n"
599             "\nGet unspent transactions\n"
600             + HelpExampleCli("listunspent", "") +
601             "\nView the details\n"
602             + HelpExampleCli("gettxout", "\"txid\" 1") +
603             "\nAs a json rpc call\n"
604             + HelpExampleRpc("gettxout", "\"txid\", 1")
605         );
606
607     LOCK(cs_main);
608
609     Object ret;
610
611     std::string strHash = params[0].get_str();
612     uint256 hash(uint256S(strHash));
613     int n = params[1].get_int();
614     bool fMempool = true;
615     if (params.size() > 2)
616         fMempool = params[2].get_bool();
617
618     CCoins coins;
619     if (fMempool) {
620         LOCK(mempool.cs);
621         CCoinsViewMemPool view(pcoinsTip, mempool);
622         if (!view.GetCoins(hash, coins))
623             return Value::null;
624         mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
625     } else {
626         if (!pcoinsTip->GetCoins(hash, coins))
627             return Value::null;
628     }
629     if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
630         return Value::null;
631
632     BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
633     CBlockIndex *pindex = it->second;
634     ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
635     if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
636         ret.push_back(Pair("confirmations", 0));
637     else ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
638     ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
639     uint64_t interest; int32_t txheight; uint32_t locktime;
640     if ( (interest= komodo_accrued_interest(&txheight,&locktime,hash,n,coins.nHeight,coins.vout[n].nValue)) != 0 )
641         ret.push_back(Pair("interest", ValueFromAmount(interest)));
642     Object o;
643     ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
644     ret.push_back(Pair("scriptPubKey", o));
645     ret.push_back(Pair("version", coins.nVersion));
646     ret.push_back(Pair("coinbase", coins.fCoinBase));
647
648     return ret;
649 }
650
651 int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n)
652 {
653     int32_t i,m; uint8_t *ptr;
654     LOCK(cs_main);
655     CCoins coins;
656     if ( 1 )
657     {
658         LOCK(mempool.cs);
659         CCoinsViewMemPool view(pcoinsTip,mempool);
660         if ( view.GetCoins(txid,coins) == 0 )
661             return(-1);
662         mempool.pruneSpent(txid, coins); // TODO: this should be done by the CCoinsViewMemPool
663     } else if ( pcoinsTip->GetCoins(txid,coins) == 0 )
664         return(-1);
665     if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
666         return(-1);
667     ptr = (uint8_t *)coins.vout[n].scriptPubKey.data();
668     m = coins.vout[n].scriptPubKey.size();
669     for (i=0; i<maxsize&&i<m; i++)
670         scriptPubKey[i] = ptr[i];
671     return(i);
672 }
673
674 Value verifychain(const Array& params, bool fHelp)
675 {
676     if (fHelp || params.size() > 2)
677         throw runtime_error(
678             "verifychain ( checklevel numblocks )\n"
679             "\nVerifies blockchain database.\n"
680             "\nArguments:\n"
681             "1. checklevel   (numeric, optional, 0-4, default=3) How thorough the block verification is.\n"
682             "2. numblocks    (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
683             "\nResult:\n"
684             "true|false       (boolean) Verified or not\n"
685             "\nExamples:\n"
686             + HelpExampleCli("verifychain", "")
687             + HelpExampleRpc("verifychain", "")
688         );
689
690     LOCK(cs_main);
691
692     int nCheckLevel = GetArg("-checklevel", 3);
693     int nCheckDepth = GetArg("-checkblocks", 288);
694     if (params.size() > 0)
695         nCheckLevel = params[0].get_int();
696     if (params.size() > 1)
697         nCheckDepth = params[1].get_int();
698
699     return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth);
700 }
701
702 /** Implementation of IsSuperMajority with better feedback */
703 Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
704 {
705     int nFound = 0;
706     CBlockIndex* pstart = pindex;
707     for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
708     {
709         if (pstart->nVersion >= minVersion)
710             ++nFound;
711         pstart = pstart->pprev;
712     }
713
714     Object rv;
715     rv.push_back(Pair("status", nFound >= nRequired));
716     rv.push_back(Pair("found", nFound));
717     rv.push_back(Pair("required", nRequired));
718     rv.push_back(Pair("window", consensusParams.nMajorityWindow));
719     return rv;
720 }
721
722 Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
723 {
724     Object rv;
725     rv.push_back(Pair("id", name));
726     rv.push_back(Pair("version", version));
727     rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
728     rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
729     return rv;
730 }
731
732 Value getblockchaininfo(const Array& params, bool fHelp)
733 {
734     if (fHelp || params.size() != 0)
735         throw runtime_error(
736             "getblockchaininfo\n"
737             "Returns an object containing various state info regarding block chain processing.\n"
738             "\nResult:\n"
739             "{\n"
740             "  \"chain\": \"xxxx\",        (string) current network name as defined in BIP70 (main, test, regtest)\n"
741             "  \"blocks\": xxxxxx,         (numeric) the current number of blocks processed in the server\n"
742             "  \"headers\": xxxxxx,        (numeric) the current number of headers we have validated\n"
743             "  \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
744             "  \"difficulty\": xxxxxx,     (numeric) the current difficulty\n"
745             "  \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
746             "  \"chainwork\": \"xxxx\"     (string) total amount of work in active chain, in hexadecimal\n"
747             "  \"softforks\": [            (array) status of softforks in progress\n"
748             "     {\n"
749             "        \"id\": \"xxxx\",        (string) name of softfork\n"
750             "        \"version\": xx,         (numeric) block version\n"
751             "        \"enforce\": {           (object) progress toward enforcing the softfork rules for new-version blocks\n"
752             "           \"status\": xx,       (boolean) true if threshold reached\n"
753             "           \"found\": xx,        (numeric) number of blocks with the new version found\n"
754             "           \"required\": xx,     (numeric) number of blocks required to trigger\n"
755             "           \"window\": xx,       (numeric) maximum size of examined window of recent blocks\n"
756             "        },\n"
757             "        \"reject\": { ... }      (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
758             "     }, ...\n"
759             "  ]\n"
760             "}\n"
761             "\nExamples:\n"
762             + HelpExampleCli("getblockchaininfo", "")
763             + HelpExampleRpc("getblockchaininfo", "")
764         );
765
766     LOCK(cs_main);
767
768     Object obj;
769     obj.push_back(Pair("chain",                 Params().NetworkIDString()));
770     obj.push_back(Pair("blocks",                (int)chainActive.Height()));
771     obj.push_back(Pair("headers",               pindexBestHeader ? pindexBestHeader->nHeight : -1));
772     obj.push_back(Pair("bestblockhash",         chainActive.Tip()->GetBlockHash().GetHex()));
773     obj.push_back(Pair("difficulty",            (double)GetNetworkDifficulty()));
774     obj.push_back(Pair("verificationprogress",  Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
775     obj.push_back(Pair("chainwork",             chainActive.Tip()->nChainWork.GetHex()));
776     obj.push_back(Pair("pruned",                fPruneMode));
777
778     const Consensus::Params& consensusParams = Params().GetConsensus();
779     CBlockIndex* tip = chainActive.Tip();
780     Array softforks;
781     softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
782     softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
783     softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
784     obj.push_back(Pair("softforks",             softforks));
785
786     if (fPruneMode)
787     {
788         CBlockIndex *block = chainActive.Tip();
789         while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
790             block = block->pprev;
791
792         obj.push_back(Pair("pruneheight",        block->nHeight));
793     }
794     return obj;
795 }
796
797 /** Comparison function for sorting the getchaintips heads.  */
798 struct CompareBlocksByHeight
799 {
800     bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
801     {
802         /* Make sure that unequal blocks with the same height do not compare
803            equal. Use the pointers themselves to make a distinction. */
804
805         if (a->nHeight != b->nHeight)
806           return (a->nHeight > b->nHeight);
807
808         return a < b;
809     }
810 };
811
812 Value getchaintips(const Array& params, bool fHelp)
813 {
814     if (fHelp || params.size() != 0)
815         throw runtime_error(
816             "getchaintips\n"
817             "Return information about all known tips in the block tree,"
818             " including the main chain as well as orphaned branches.\n"
819             "\nResult:\n"
820             "[\n"
821             "  {\n"
822             "    \"height\": xxxx,         (numeric) height of the chain tip\n"
823             "    \"hash\": \"xxxx\",         (string) block hash of the tip\n"
824             "    \"branchlen\": 0          (numeric) zero for main chain\n"
825             "    \"status\": \"active\"      (string) \"active\" for the main chain\n"
826             "  },\n"
827             "  {\n"
828             "    \"height\": xxxx,\n"
829             "    \"hash\": \"xxxx\",\n"
830             "    \"branchlen\": 1          (numeric) length of branch connecting the tip to the main chain\n"
831             "    \"status\": \"xxxx\"        (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
832             "  }\n"
833             "]\n"
834             "Possible values for status:\n"
835             "1.  \"invalid\"               This branch contains at least one invalid block\n"
836             "2.  \"headers-only\"          Not all blocks for this branch are available, but the headers are valid\n"
837             "3.  \"valid-headers\"         All blocks are available for this branch, but they were never fully validated\n"
838             "4.  \"valid-fork\"            This branch is not part of the active chain, but is fully validated\n"
839             "5.  \"active\"                This is the tip of the active main chain, which is certainly valid\n"
840             "\nExamples:\n"
841             + HelpExampleCli("getchaintips", "")
842             + HelpExampleRpc("getchaintips", "")
843         );
844
845     LOCK(cs_main);
846
847     /* Build up a list of chain tips.  We start with the list of all
848        known blocks, and successively remove blocks that appear as pprev
849        of another block.  */
850     std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
851     BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
852         setTips.insert(item.second);
853     BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
854     {
855         const CBlockIndex* pprev = item.second->pprev;
856         if (pprev)
857             setTips.erase(pprev);
858     }
859
860     // Always report the currently active tip.
861     setTips.insert(chainActive.Tip());
862
863     /* Construct the output array.  */
864     Array res;
865     BOOST_FOREACH(const CBlockIndex* block, setTips)
866     {
867         Object obj;
868         obj.push_back(Pair("height", block->nHeight));
869         obj.push_back(Pair("hash", block->phashBlock->GetHex()));
870
871         const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
872         obj.push_back(Pair("branchlen", branchLen));
873
874         string status;
875         if (chainActive.Contains(block)) {
876             // This block is part of the currently active chain.
877             status = "active";
878         } else if (block->nStatus & BLOCK_FAILED_MASK) {
879             // This block or one of its ancestors is invalid.
880             status = "invalid";
881         } else if (block->nChainTx == 0) {
882             // This block cannot be connected because full block data for it or one of its parents is missing.
883             status = "headers-only";
884         } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
885             // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
886             status = "valid-fork";
887         } else if (block->IsValid(BLOCK_VALID_TREE)) {
888             // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
889             status = "valid-headers";
890         } else {
891             // No clue.
892             status = "unknown";
893         }
894         obj.push_back(Pair("status", status));
895
896         res.push_back(obj);
897     }
898
899     return res;
900 }
901
902 Value getmempoolinfo(const Array& params, bool fHelp)
903 {
904     if (fHelp || params.size() != 0)
905         throw runtime_error(
906             "getmempoolinfo\n"
907             "\nReturns details on the active state of the TX memory pool.\n"
908             "\nResult:\n"
909             "{\n"
910             "  \"size\": xxxxx                (numeric) Current tx count\n"
911             "  \"bytes\": xxxxx               (numeric) Sum of all tx sizes\n"
912             "}\n"
913             "\nExamples:\n"
914             + HelpExampleCli("getmempoolinfo", "")
915             + HelpExampleRpc("getmempoolinfo", "")
916         );
917
918     Object ret;
919     ret.push_back(Pair("size", (int64_t) mempool.size()));
920     ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
921
922     return ret;
923 }
924
925 Value invalidateblock(const Array& params, bool fHelp)
926 {
927     if (fHelp || params.size() != 1)
928         throw runtime_error(
929             "invalidateblock \"hash\"\n"
930             "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
931             "\nArguments:\n"
932             "1. hash   (string, required) the hash of the block to mark as invalid\n"
933             "\nResult:\n"
934             "\nExamples:\n"
935             + HelpExampleCli("invalidateblock", "\"blockhash\"")
936             + HelpExampleRpc("invalidateblock", "\"blockhash\"")
937         );
938
939     std::string strHash = params[0].get_str();
940     uint256 hash(uint256S(strHash));
941     CValidationState state;
942
943     {
944         LOCK(cs_main);
945         if (mapBlockIndex.count(hash) == 0)
946             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
947
948         CBlockIndex* pblockindex = mapBlockIndex[hash];
949         InvalidateBlock(state, pblockindex);
950     }
951
952     if (state.IsValid()) {
953         ActivateBestChain(state);
954     }
955
956     if (!state.IsValid()) {
957         throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
958     }
959
960     return Value::null;
961 }
962
963 Value reconsiderblock(const Array& params, bool fHelp)
964 {
965     if (fHelp || params.size() != 1)
966         throw runtime_error(
967             "reconsiderblock \"hash\"\n"
968             "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
969             "This can be used to undo the effects of invalidateblock.\n"
970             "\nArguments:\n"
971             "1. hash   (string, required) the hash of the block to reconsider\n"
972             "\nResult:\n"
973             "\nExamples:\n"
974             + HelpExampleCli("reconsiderblock", "\"blockhash\"")
975             + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
976         );
977
978     std::string strHash = params[0].get_str();
979     uint256 hash(uint256S(strHash));
980     CValidationState state;
981
982     {
983         LOCK(cs_main);
984         if (mapBlockIndex.count(hash) == 0)
985             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
986
987         CBlockIndex* pblockindex = mapBlockIndex[hash];
988         ReconsiderBlock(state, pblockindex);
989     }
990
991     if (state.IsValid()) {
992         ActivateBestChain(state);
993     }
994
995     if (!state.IsValid()) {
996         throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
997     }
998
999     return Value::null;
1000 }
This page took 0.084836 seconds and 4 git commands to generate.