Dogecoin Core  1.14.2
P2P Digital Currency
rest.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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 "chain.h"
7 #include "chainparams.h"
8 #include "primitives/block.h"
10 #include "validation.h"
11 #include "httpserver.h"
12 #include "rpc/server.h"
13 #include "streams.h"
14 #include "sync.h"
15 #include "txmempool.h"
16 #include "utilstrencodings.h"
17 #include "version.h"
18 
19 #include <boost/algorithm/string.hpp>
20 
21 #include <univalue.h>
22 
23 static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once
24 
25 enum RetFormat {
30 };
31 
32 static const struct {
33  enum RetFormat rf;
34  const char* name;
35 } rf_names[] = {
36  {RF_UNDEF, ""},
37  {RF_BINARY, "bin"},
38  {RF_HEX, "hex"},
39  {RF_JSON, "json"},
40 };
41 
42 struct CCoin {
43  uint32_t nTxVer; // Don't call this nVersion, that name has a special meaning inside IMPLEMENT_SERIALIZE
44  uint32_t nHeight;
46 
48 
49  template <typename Stream, typename Operation>
50  inline void SerializationOp(Stream& s, Operation ser_action)
51  {
54  READWRITE(out);
55  }
56 };
57 
58 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
59 extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
61 extern UniValue mempoolToJSON(bool fVerbose = false);
62 extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
63 extern UniValue blockheaderToJSON(const CBlockIndex* blockindex);
64 
65 static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string message)
66 {
67  req->WriteHeader("Content-Type", "text/plain");
68  req->WriteReply(status, message + "\r\n");
69  return false;
70 }
71 
72 static enum RetFormat ParseDataFormat(std::string& param, const std::string& strReq)
73 {
74  const std::string::size_type pos = strReq.rfind('.');
75  if (pos == std::string::npos)
76  {
77  param = strReq;
78  return rf_names[0].rf;
79  }
80 
81  param = strReq.substr(0, pos);
82  const std::string suff(strReq, pos + 1);
83 
84  for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
85  if (suff == rf_names[i].name)
86  return rf_names[i].rf;
87 
88  /* If no suffix is found, return original string. */
89  param = strReq;
90  return rf_names[0].rf;
91 }
92 
93 static std::string AvailableDataFormatsString()
94 {
95  std::string formats = "";
96  for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
97  if (strlen(rf_names[i].name) > 0) {
98  formats.append(".");
99  formats.append(rf_names[i].name);
100  formats.append(", ");
101  }
102 
103  if (formats.length() > 0)
104  return formats.substr(0, formats.length() - 2);
105 
106  return formats;
107 }
108 
109 static bool ParseHashStr(const std::string& strReq, uint256& v)
110 {
111  if (!IsHex(strReq) || (strReq.size() != 64))
112  return false;
113 
114  v.SetHex(strReq);
115  return true;
116 }
117 
118 static bool CheckWarmup(HTTPRequest* req)
119 {
120  std::string statusmessage;
121  if (RPCIsInWarmup(&statusmessage))
122  return RESTERR(req, HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage);
123  return true;
124 }
125 
126 static bool rest_headers(HTTPRequest* req,
127  const std::string& strURIPart)
128 {
129  if (!CheckWarmup(req))
130  return false;
131  std::string param;
132  const RetFormat rf = ParseDataFormat(param, strURIPart);
133  std::vector<std::string> path;
134  boost::split(path, param, boost::is_any_of("/"));
135 
136  if (path.size() != 2)
137  return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>.");
138 
139  long count = strtol(path[0].c_str(), NULL, 10);
140  if (count < 1 || count > 2000)
141  return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]);
142 
143  std::string hashStr = path[1];
144  uint256 hash;
145  if (!ParseHashStr(hashStr, hash))
146  return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
147 
148  std::vector<const CBlockIndex *> headers;
149  headers.reserve(count);
150  {
151  LOCK(cs_main);
152  BlockMap::const_iterator it = mapBlockIndex.find(hash);
153  const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL;
154  while (pindex != NULL && chainActive.Contains(pindex)) {
155  headers.push_back(pindex);
156  if (headers.size() == (unsigned long)count)
157  break;
158  pindex = chainActive.Next(pindex);
159  }
160  }
161 
162  CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
163  const CChainParams& chainparams = Params();
164  BOOST_FOREACH(const CBlockIndex *pindex, headers) {
165  ssHeader << pindex->GetBlockHeader(chainparams.GetConsensus(pindex->nHeight));
166  }
167 
168  switch (rf) {
169  case RF_BINARY: {
170  std::string binaryHeader = ssHeader.str();
171  req->WriteHeader("Content-Type", "application/octet-stream");
172  req->WriteReply(HTTP_OK, binaryHeader);
173  return true;
174  }
175 
176  case RF_HEX: {
177  std::string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n";
178  req->WriteHeader("Content-Type", "text/plain");
179  req->WriteReply(HTTP_OK, strHex);
180  return true;
181  }
182  case RF_JSON: {
183  UniValue jsonHeaders(UniValue::VARR);
184  BOOST_FOREACH(const CBlockIndex *pindex, headers) {
185  jsonHeaders.push_back(blockheaderToJSON(pindex));
186  }
187  std::string strJSON = jsonHeaders.write() + "\n";
188  req->WriteHeader("Content-Type", "application/json");
189  req->WriteReply(HTTP_OK, strJSON);
190  return true;
191  }
192  default: {
193  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)");
194  }
195  }
196 
197  // not reached
198  return true; // continue to process further HTTP reqs on this cxn
199 }
200 
201 static bool rest_block(HTTPRequest* req,
202  const std::string& strURIPart,
203  bool showTxDetails)
204 {
205  if (!CheckWarmup(req))
206  return false;
207  std::string hashStr;
208  const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
209 
210  uint256 hash;
211  if (!ParseHashStr(hashStr, hash))
212  return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
213 
214  CBlock block;
215  CBlockIndex* pblockindex = NULL;
216  {
217  LOCK(cs_main);
218  if (mapBlockIndex.count(hash) == 0)
219  return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
220 
221  pblockindex = mapBlockIndex[hash];
222  if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
223  return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
224 
225  if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus(pblockindex->nHeight)))
226  return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
227  }
228 
229  CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
230  ssBlock << block;
231 
232  switch (rf) {
233  case RF_BINARY: {
234  std::string binaryBlock = ssBlock.str();
235  req->WriteHeader("Content-Type", "application/octet-stream");
236  req->WriteReply(HTTP_OK, binaryBlock);
237  return true;
238  }
239 
240  case RF_HEX: {
241  std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";
242  req->WriteHeader("Content-Type", "text/plain");
243  req->WriteReply(HTTP_OK, strHex);
244  return true;
245  }
246 
247  case RF_JSON: {
248  UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails);
249  std::string strJSON = objBlock.write() + "\n";
250  req->WriteHeader("Content-Type", "application/json");
251  req->WriteReply(HTTP_OK, strJSON);
252  return true;
253  }
254 
255  default: {
256  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
257  }
258  }
259 
260  // not reached
261  return true; // continue to process further HTTP reqs on this cxn
262 }
263 
264 static bool rest_block_extended(HTTPRequest* req, const std::string& strURIPart)
265 {
266  return rest_block(req, strURIPart, true);
267 }
268 
269 static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPart)
270 {
271  return rest_block(req, strURIPart, false);
272 }
273 
274 // A bit of a hack - dependency on a function defined in rpc/blockchain.cpp
276 
277 static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart)
278 {
279  if (!CheckWarmup(req))
280  return false;
281  std::string param;
282  const RetFormat rf = ParseDataFormat(param, strURIPart);
283 
284  switch (rf) {
285  case RF_JSON: {
286  JSONRPCRequest jsonRequest;
287  jsonRequest.params = UniValue(UniValue::VARR);
288  UniValue chainInfoObject = getblockchaininfo(jsonRequest);
289  std::string strJSON = chainInfoObject.write() + "\n";
290  req->WriteHeader("Content-Type", "application/json");
291  req->WriteReply(HTTP_OK, strJSON);
292  return true;
293  }
294  default: {
295  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
296  }
297  }
298 
299  // not reached
300  return true; // continue to process further HTTP reqs on this cxn
301 }
302 
303 static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
304 {
305  if (!CheckWarmup(req))
306  return false;
307  std::string param;
308  const RetFormat rf = ParseDataFormat(param, strURIPart);
309 
310  switch (rf) {
311  case RF_JSON: {
312  UniValue mempoolInfoObject = mempoolInfoToJSON();
313 
314  std::string strJSON = mempoolInfoObject.write() + "\n";
315  req->WriteHeader("Content-Type", "application/json");
316  req->WriteReply(HTTP_OK, strJSON);
317  return true;
318  }
319  default: {
320  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
321  }
322  }
323 
324  // not reached
325  return true; // continue to process further HTTP reqs on this cxn
326 }
327 
328 static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart)
329 {
330  if (!CheckWarmup(req))
331  return false;
332  std::string param;
333  const RetFormat rf = ParseDataFormat(param, strURIPart);
334 
335  switch (rf) {
336  case RF_JSON: {
337  UniValue mempoolObject = mempoolToJSON(true);
338 
339  std::string strJSON = mempoolObject.write() + "\n";
340  req->WriteHeader("Content-Type", "application/json");
341  req->WriteReply(HTTP_OK, strJSON);
342  return true;
343  }
344  default: {
345  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
346  }
347  }
348 
349  // not reached
350  return true; // continue to process further HTTP reqs on this cxn
351 }
352 
353 static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
354 {
355  if (!CheckWarmup(req))
356  return false;
357  std::string hashStr;
358  const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
359 
360  uint256 hash;
361  if (!ParseHashStr(hashStr, hash))
362  return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
363 
364  CTransactionRef tx;
365  uint256 hashBlock = uint256();
366  if (!GetTransaction(hash, tx, Params().GetConsensus(0), hashBlock, true))
367  return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
368 
369  CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
370  ssTx << tx;
371 
372  switch (rf) {
373  case RF_BINARY: {
374  std::string binaryTx = ssTx.str();
375  req->WriteHeader("Content-Type", "application/octet-stream");
376  req->WriteReply(HTTP_OK, binaryTx);
377  return true;
378  }
379 
380  case RF_HEX: {
381  std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";
382  req->WriteHeader("Content-Type", "text/plain");
383  req->WriteReply(HTTP_OK, strHex);
384  return true;
385  }
386 
387  case RF_JSON: {
388  UniValue objTx(UniValue::VOBJ);
389  TxToJSON(*tx, hashBlock, objTx);
390  std::string strJSON = objTx.write() + "\n";
391  req->WriteHeader("Content-Type", "application/json");
392  req->WriteReply(HTTP_OK, strJSON);
393  return true;
394  }
395 
396  default: {
397  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
398  }
399  }
400 
401  // not reached
402  return true; // continue to process further HTTP reqs on this cxn
403 }
404 
405 static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
406 {
407  if (!CheckWarmup(req))
408  return false;
409  std::string param;
410  const RetFormat rf = ParseDataFormat(param, strURIPart);
411 
412  std::vector<std::string> uriParts;
413  if (param.length() > 1)
414  {
415  std::string strUriParams = param.substr(1);
416  boost::split(uriParts, strUriParams, boost::is_any_of("/"));
417  }
418 
419  // throw exception in case of a empty request
420  std::string strRequestMutable = req->ReadBody();
421  if (strRequestMutable.length() == 0 && uriParts.size() == 0)
422  return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
423 
424  bool fInputParsed = false;
425  bool fCheckMemPool = false;
426  std::vector<COutPoint> vOutPoints;
427 
428  // parse/deserialize input
429  // input-format = output-format, rest/getutxos/bin requires binary input, gives binary output, ...
430 
431  if (uriParts.size() > 0)
432  {
433 
434  //inputs is sent over URI scheme (/rest/getutxos/checkmempool/txid1-n/txid2-n/...)
435  if (uriParts.size() > 0 && uriParts[0] == "checkmempool")
436  fCheckMemPool = true;
437 
438  for (size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
439  {
440  uint256 txid;
441  int32_t nOutput;
442  std::string strTxid = uriParts[i].substr(0, uriParts[i].find("-"));
443  std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1);
444 
445  if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid))
446  return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
447 
448  txid.SetHex(strTxid);
449  vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput));
450  }
451 
452  if (vOutPoints.size() > 0)
453  fInputParsed = true;
454  else
455  return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
456  }
457 
458  switch (rf) {
459  case RF_HEX: {
460  // convert hex to bin, continue then with bin part
461  std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable);
462  strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
463  }
464 
465  case RF_BINARY: {
466  try {
467  //deserialize only if user sent a request
468  if (strRequestMutable.size() > 0)
469  {
470  if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA
471  return RESTERR(req, HTTP_BAD_REQUEST, "Combination of URI scheme inputs and raw post data is not allowed");
472 
473  CDataStream oss(SER_NETWORK, PROTOCOL_VERSION);
474  oss << strRequestMutable;
475  oss >> fCheckMemPool;
476  oss >> vOutPoints;
477  }
478  } catch (const std::ios_base::failure& e) {
479  // abort in case of unreadable binary data
480  return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
481  }
482  break;
483  }
484 
485  case RF_JSON: {
486  if (!fInputParsed)
487  return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
488  break;
489  }
490  default: {
491  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
492  }
493  }
494 
495  // limit max outpoints
496  if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS)
497  return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size()));
498 
499  // check spentness and form a bitmap (as well as a JSON capable human-readable string representation)
500  std::vector<unsigned char> bitmap;
501  std::vector<CCoin> outs;
502  std::string bitmapStringRepresentation;
503  std::vector<bool> hits;
504  bitmap.resize((vOutPoints.size() + 7) / 8);
505  {
507 
508  CCoinsView viewDummy;
509  CCoinsViewCache view(&viewDummy);
510 
511  CCoinsViewCache& viewChain = *pcoinsTip;
512  CCoinsViewMemPool viewMempool(&viewChain, mempool);
513 
514  if (fCheckMemPool)
515  view.SetBackend(viewMempool); // switch cache backend to db+mempool in case user likes to query mempool
516 
517  for (size_t i = 0; i < vOutPoints.size(); i++) {
518  CCoins coins;
519  uint256 hash = vOutPoints[i].hash;
520  bool hit = false;
521  if (view.GetCoins(hash, coins)) {
522  mempool.pruneSpent(hash, coins);
523  if (coins.IsAvailable(vOutPoints[i].n)) {
524  hit = true;
525  // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if
526  // n is valid but points to an already spent output (IsNull).
527  CCoin coin;
528  coin.nTxVer = coins.nVersion;
529  coin.nHeight = coins.nHeight;
530  coin.out = coins.vout.at(vOutPoints[i].n);
531  assert(!coin.out.IsNull());
532  outs.push_back(coin);
533  }
534  }
535 
536  hits.push_back(hit);
537  bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output)
538  bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
539  }
540  }
541 
542  switch (rf) {
543  case RF_BINARY: {
544  // serialize data
545  // use exact same output as mentioned in Bip64
546  CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
547  ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
548  std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();
549 
550  req->WriteHeader("Content-Type", "application/octet-stream");
551  req->WriteReply(HTTP_OK, ssGetUTXOResponseString);
552  return true;
553  }
554 
555  case RF_HEX: {
556  CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
557  ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
558  std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n";
559 
560  req->WriteHeader("Content-Type", "text/plain");
561  req->WriteReply(HTTP_OK, strHex);
562  return true;
563  }
564 
565  case RF_JSON: {
566  UniValue objGetUTXOResponse(UniValue::VOBJ);
567 
568  // pack in some essentials
569  // use more or less the same output as mentioned in Bip64
570  objGetUTXOResponse.push_back(Pair("chainHeight", chainActive.Height()));
571  objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()));
572  objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation));
573 
574  UniValue utxos(UniValue::VARR);
575  BOOST_FOREACH (const CCoin& coin, outs) {
576  UniValue utxo(UniValue::VOBJ);
577  utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer));
578  utxo.push_back(Pair("height", (int32_t)coin.nHeight));
579  utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
580 
581  // include the script in a json output
583  ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true);
584  utxo.push_back(Pair("scriptPubKey", o));
585  utxos.push_back(utxo);
586  }
587  objGetUTXOResponse.push_back(Pair("utxos", utxos));
588 
589  // return json string
590  std::string strJSON = objGetUTXOResponse.write() + "\n";
591  req->WriteHeader("Content-Type", "application/json");
592  req->WriteReply(HTTP_OK, strJSON);
593  return true;
594  }
595  default: {
596  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
597  }
598  }
599 
600  // not reached
601  return true; // continue to process further HTTP reqs on this cxn
602 }
603 
604 static const struct {
605  const char* prefix;
606  bool (*handler)(HTTPRequest* req, const std::string& strReq);
607 } uri_prefixes[] = {
608  {"/rest/tx/", rest_tx},
609  {"/rest/block/notxdetails/", rest_block_notxdetails},
610  {"/rest/block/", rest_block_extended},
611  {"/rest/chaininfo", rest_chaininfo},
612  {"/rest/mempool/info", rest_mempool_info},
613  {"/rest/mempool/contents", rest_mempool_contents},
614  {"/rest/headers/", rest_headers},
615  {"/rest/getutxos", rest_getutxos},
616 };
617 
618 bool StartREST()
619 {
620  for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
621  RegisterHTTPHandler(uri_prefixes[i].prefix, false, uri_prefixes[i].handler);
622  return true;
623 }
624 
626 {
627 }
628 
629 void StopREST()
630 {
631  for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
632  UnregisterHTTPHandler(uri_prefixes[i].prefix, false);
633 }
@ BLOCK_HAVE_DATA
full block available in blk*.dat
Definition: chain.h:141
const CChainParams & Params()
Return the currently selected parameters.
Definition: block.h:67
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:158
CBlockHeader GetBlockHeader(const Consensus::Params &consensusParams, bool fCheckPOW=true) const
Definition: chain.cpp:13
uint256 GetBlockHash() const
Definition: chain.h:268
unsigned int nStatus
Verification status of this block. See enum BlockStatus.
Definition: chain.h:194
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:186
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:170
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or NULL if the given index is not found or is the tip.
Definition: chain.h:466
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or NULL if none.
Definition: chain.h:443
int Height() const
Return the maximal height in the chain.
Definition: chain.h:474
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:461
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:47
const Consensus::Params & GetConsensus(uint32_t nTargetHeight) const
Definition: chainparams.h:59
Pruned version of CTransaction: only retains metadata and unspent transaction outputs.
Definition: coins.h:75
std::vector< CTxOut > vout
unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are d...
Definition: coins.h:81
int nVersion
version of the CTransaction; accesses to this value should probably check for nHeight as well,...
Definition: coins.h:88
bool IsAvailable(unsigned int nPos) const
check whether a particular output is still available
Definition: coins.h:223
int nHeight
at which height this transaction was included in the active block chain
Definition: coins.h:84
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:372
Abstract view on the open txout dataset.
Definition: coins.h:307
CCoinsView that brings transactions from a memorypool into view.
Definition: txmempool.h:713
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:20
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:377
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:308
CCriticalSection cs
Definition: txmempool.h:483
void pruneSpent(const uint256 &hash, CCoins &coins)
Definition: txmempool.cpp:370
An output of a transaction.
Definition: transaction.h:133
CScript scriptPubKey
Definition: transaction.h:136
CAmount nValue
Definition: transaction.h:135
bool IsNull() const
Definition: transaction.h:159
In-flight HTTP request.
Definition: httpserver.h:54
void WriteReply(int nStatus, const std::string &strReply="")
Write HTTP reply.
Definition: httpserver.cpp:600
void WriteHeader(const std::string &hdr, const std::string &value)
Write output header.
Definition: httpserver.cpp:588
std::string ReadBody()
Read request body.
Definition: httpserver.cpp:568
UniValue params
Definition: server.h:52
@ VOBJ
Definition: univalue.h:21
@ VARR
Definition: univalue.h:21
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
void SetHex(const char *psz)
Definition: uint256.cpp:30
std::string GetHex() const
Definition: uint256.cpp:21
256-bit opaque blob.
Definition: uint256.h:123
uint256 ParseHashStr(const std::string &, const std::string &strName)
Definition: core_read.cpp:149
void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch)
Unregister handler for prefix.
Definition: httpserver.cpp:660
void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler)
Register handler for prefix.
Definition: httpserver.cpp:654
UniValue mempoolToJSON(bool fVerbose=false)
Definition: blockchain.cpp:426
UniValue getblockchaininfo(const JSONRPCRequest &request)
const char * prefix
Definition: rest.cpp:605
UniValue blockToJSON(const CBlock &block, const CBlockIndex *blockindex, bool txDetails=false)
Definition: blockchain.cpp:142
void ScriptPubKeyToJSON(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
void TxToJSON(const CTransaction &tx, const uint256 hashBlock, UniValue &entry)
UniValue mempoolInfoToJSON()
void StopREST()
Stop HTTP REST subsystem.
Definition: rest.cpp:629
bool StartREST()
Start HTTP REST subsystem.
Definition: rest.cpp:618
UniValue blockheaderToJSON(const CBlockIndex *blockindex)
Definition: blockchain.cpp:114
RetFormat
Definition: rest.cpp:25
@ RF_HEX
Definition: rest.cpp:28
@ RF_UNDEF
Definition: rest.cpp:26
@ RF_BINARY
Definition: rest.cpp:27
@ RF_JSON
Definition: rest.cpp:29
void InterruptREST()
Interrupt RPC REST subsystem.
Definition: rest.cpp:625
bool(* handler)(HTTPRequest *req, const std::string &strReq)
Definition: rest.cpp:606
HTTPStatusCode
HTTP status codes.
Definition: protocol.h:19
@ HTTP_BAD_REQUEST
Definition: protocol.h:21
@ HTTP_OK
Definition: protocol.h:20
@ HTTP_SERVICE_UNAVAILABLE
Definition: protocol.h:27
@ HTTP_NOT_FOUND
Definition: protocol.h:24
#define READWRITE(obj)
Definition: serialize.h:151
@ SER_NETWORK
Definition: serialize.h:146
bool RPCIsInWarmup(std::string *outStatus)
Definition: server.cpp:366
UniValue ValueFromAmount(const CAmount &amount)
Definition: server.cpp:136
int RPCSerializationFlags()
Definition: server.cpp:561
Definition: rest.cpp:42
CTxOut out
Definition: rest.cpp:45
uint32_t nTxVer
Definition: rest.cpp:43
void SerializationOp(Stream &s, Operation ser_action)
Definition: rest.cpp:50
ADD_SERIALIZE_METHODS
Definition: rest.cpp:47
uint32_t nHeight
Definition: rest.cpp:44
#define LOCK2(cs1, cs2)
Definition: sync.h:178
#define LOCK(cs)
Definition: sync.h:177
#define strprintf
Definition: tinyformat.h:1047
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:459
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
bool IsHex(const string &str)
vector< unsigned char > ParseHex(const char *psz)
#define ARRAYLEN(array)
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: validation.cpp:223
CCriticalSection cs_main
Global state.
Definition: validation.cpp:61
bool fHavePruned
Pruning-related variables and constants.
Definition: validation.cpp:72
CTxMemPool mempool(::minRelayTxFee)
bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus::Params &consensusParams, uint256 &hashBlock, bool fAllowSlow)
Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock.
BlockMap mapBlockIndex
Definition: validation.cpp:63
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams, bool fCheckPOW)
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:64