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