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