BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
rest.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 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 <index/txindex.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 class RetFormat {
29  UNDEF,
30  BINARY,
31  HEX,
32  JSON,
33 };
34 
35 static const struct {
37  const char* name;
38 } rf_names[] = {
39  {RetFormat::UNDEF, ""},
40  {RetFormat::BINARY, "bin"},
41  {RetFormat::HEX, "hex"},
42  {RetFormat::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);
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 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 CheckWarmup(HTTPRequest* req)
109 {
110  std::string statusmessage;
111  if (RPCIsInWarmup(&statusmessage))
112  return RESTERR(req, HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage);
113  return true;
114 }
115 
116 static bool rest_headers(HTTPRequest* req,
117  const std::string& strURIPart)
118 {
119  if (!CheckWarmup(req))
120  return false;
121  std::string param;
122  const RetFormat rf = ParseDataFormat(param, strURIPart);
123  std::vector<std::string> path;
124  boost::split(path, param, boost::is_any_of("/"));
125 
126  if (path.size() != 2)
127  return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>.");
128 
129  long count = strtol(path[0].c_str(), nullptr, 10);
130  if (count < 1 || count > 2000)
131  return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]);
132 
133  std::string hashStr = path[1];
134  uint256 hash;
135  if (!ParseHashStr(hashStr, hash))
136  return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
137 
138  std::vector<const CBlockIndex *> headers;
139  headers.reserve(count);
140  {
141  LOCK(cs_main);
142  const CBlockIndex* pindex = LookupBlockIndex(hash);
143  while (pindex != nullptr && chainActive.Contains(pindex)) {
144  headers.push_back(pindex);
145  if (headers.size() == (unsigned long)count)
146  break;
147  pindex = chainActive.Next(pindex);
148  }
149  }
150 
151  switch (rf) {
152  case RetFormat::BINARY: {
153  CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
154  for (const CBlockIndex *pindex : headers) {
155  ssHeader << pindex->GetBlockHeader();
156  }
157 
158  std::string binaryHeader = ssHeader.str();
159  req->WriteHeader("Content-Type", "application/octet-stream");
160  req->WriteReply(HTTP_OK, binaryHeader);
161  return true;
162  }
163 
164  case RetFormat::HEX: {
165  CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
166  for (const CBlockIndex *pindex : headers) {
167  ssHeader << pindex->GetBlockHeader();
168  }
169 
170  std::string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n";
171  req->WriteHeader("Content-Type", "text/plain");
172  req->WriteReply(HTTP_OK, strHex);
173  return true;
174  }
175  case RetFormat::JSON: {
176  UniValue jsonHeaders(UniValue::VARR);
177  {
178  LOCK(cs_main);
179  for (const CBlockIndex *pindex : headers) {
180  jsonHeaders.push_back(blockheaderToJSON(pindex));
181  }
182  }
183  std::string strJSON = jsonHeaders.write() + "\n";
184  req->WriteHeader("Content-Type", "application/json");
185  req->WriteReply(HTTP_OK, strJSON);
186  return true;
187  }
188  default: {
189  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)");
190  }
191  }
192 }
193 
194 static bool rest_block(HTTPRequest* req,
195  const std::string& strURIPart,
196  bool showTxDetails)
197 {
198  if (!CheckWarmup(req))
199  return false;
200  std::string hashStr;
201  const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
202 
203  uint256 hash;
204  if (!ParseHashStr(hashStr, hash))
205  return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
206 
207  CBlock block;
208  CBlockIndex* pblockindex = nullptr;
209  {
210  LOCK(cs_main);
211  pblockindex = LookupBlockIndex(hash);
212  if (!pblockindex) {
213  return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
214  }
215 
216  if (IsBlockPruned(pblockindex))
217  return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
218 
219  if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
220  return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
221  }
222 
223  switch (rf) {
224  case RetFormat::BINARY: {
225  CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
226  ssBlock << block;
227  std::string binaryBlock = ssBlock.str();
228  req->WriteHeader("Content-Type", "application/octet-stream");
229  req->WriteReply(HTTP_OK, binaryBlock);
230  return true;
231  }
232 
233  case RetFormat::HEX: {
234  CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
235  ssBlock << block;
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 RetFormat::JSON: {
243  UniValue objBlock;
244  {
245  LOCK(cs_main);
246  objBlock = blockToJSON(block, pblockindex, showTxDetails);
247  }
248  std::string strJSON = objBlock.write() + "\n";
249  req->WriteHeader("Content-Type", "application/json");
250  req->WriteReply(HTTP_OK, strJSON);
251  return true;
252  }
253 
254  default: {
255  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
256  }
257  }
258 }
259 
260 static bool rest_block_extended(HTTPRequest* req, const std::string& strURIPart)
261 {
262  return rest_block(req, strURIPart, true);
263 }
264 
265 static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPart)
266 {
267  return rest_block(req, strURIPart, false);
268 }
269 
270 // A bit of a hack - dependency on a function defined in rpc/blockchain.cpp
272 
273 static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart)
274 {
275  if (!CheckWarmup(req))
276  return false;
277  std::string param;
278  const RetFormat rf = ParseDataFormat(param, strURIPart);
279 
280  switch (rf) {
281  case RetFormat::JSON: {
282  JSONRPCRequest jsonRequest;
283  jsonRequest.params = UniValue(UniValue::VARR);
284  UniValue chainInfoObject = getblockchaininfo(jsonRequest);
285  std::string strJSON = chainInfoObject.write() + "\n";
286  req->WriteHeader("Content-Type", "application/json");
287  req->WriteReply(HTTP_OK, strJSON);
288  return true;
289  }
290  default: {
291  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
292  }
293  }
294 }
295 
296 static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
297 {
298  if (!CheckWarmup(req))
299  return false;
300  std::string param;
301  const RetFormat rf = ParseDataFormat(param, strURIPart);
302 
303  switch (rf) {
304  case RetFormat::JSON: {
305  UniValue mempoolInfoObject = mempoolInfoToJSON();
306 
307  std::string strJSON = mempoolInfoObject.write() + "\n";
308  req->WriteHeader("Content-Type", "application/json");
309  req->WriteReply(HTTP_OK, strJSON);
310  return true;
311  }
312  default: {
313  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
314  }
315  }
316 }
317 
318 static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart)
319 {
320  if (!CheckWarmup(req))
321  return false;
322  std::string param;
323  const RetFormat rf = ParseDataFormat(param, strURIPart);
324 
325  switch (rf) {
326  case RetFormat::JSON: {
327  UniValue mempoolObject = mempoolToJSON(true);
328 
329  std::string strJSON = mempoolObject.write() + "\n";
330  req->WriteHeader("Content-Type", "application/json");
331  req->WriteReply(HTTP_OK, strJSON);
332  return true;
333  }
334  default: {
335  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
336  }
337  }
338 }
339 
340 static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
341 {
342  if (!CheckWarmup(req))
343  return false;
344  std::string hashStr;
345  const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
346 
347  uint256 hash;
348  if (!ParseHashStr(hashStr, hash))
349  return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
350 
351  if (g_txindex) {
352  g_txindex->BlockUntilSyncedToCurrentChain();
353  }
354 
355  CTransactionRef tx;
356  uint256 hashBlock = uint256();
357  if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
358  return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
359 
360  switch (rf) {
361  case RetFormat::BINARY: {
362  CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
363  ssTx << tx;
364 
365  std::string binaryTx = ssTx.str();
366  req->WriteHeader("Content-Type", "application/octet-stream");
367  req->WriteReply(HTTP_OK, binaryTx);
368  return true;
369  }
370 
371  case RetFormat::HEX: {
372  CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
373  ssTx << tx;
374 
375  std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";
376  req->WriteHeader("Content-Type", "text/plain");
377  req->WriteReply(HTTP_OK, strHex);
378  return true;
379  }
380 
381  case RetFormat::JSON: {
382  UniValue objTx(UniValue::VOBJ);
383  TxToUniv(*tx, hashBlock, objTx);
384  std::string strJSON = objTx.write() + "\n";
385  req->WriteHeader("Content-Type", "application/json");
386  req->WriteReply(HTTP_OK, strJSON);
387  return true;
388  }
389 
390  default: {
391  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
392  }
393  }
394 }
395 
396 static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
397 {
398  if (!CheckWarmup(req))
399  return false;
400  std::string param;
401  const RetFormat rf = ParseDataFormat(param, strURIPart);
402 
403  std::vector<std::string> uriParts;
404  if (param.length() > 1)
405  {
406  std::string strUriParams = param.substr(1);
407  boost::split(uriParts, strUriParams, boost::is_any_of("/"));
408  }
409 
410  // throw exception in case of an empty request
411  std::string strRequestMutable = req->ReadBody();
412  if (strRequestMutable.length() == 0 && uriParts.size() == 0)
413  return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
414 
415  bool fInputParsed = false;
416  bool fCheckMemPool = false;
417  std::vector<COutPoint> vOutPoints;
418 
419  // parse/deserialize input
420  // input-format = output-format, rest/getutxos/bin requires binary input, gives binary output, ...
421 
422  if (uriParts.size() > 0)
423  {
424  //inputs is sent over URI scheme (/rest/getutxos/checkmempool/txid1-n/txid2-n/...)
425  if (uriParts[0] == "checkmempool") fCheckMemPool = true;
426 
427  for (size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
428  {
429  uint256 txid;
430  int32_t nOutput;
431  std::string strTxid = uriParts[i].substr(0, uriParts[i].find('-'));
432  std::string strOutput = uriParts[i].substr(uriParts[i].find('-')+1);
433 
434  if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid))
435  return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
436 
437  txid.SetHex(strTxid);
438  vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput));
439  }
440 
441  if (vOutPoints.size() > 0)
442  fInputParsed = true;
443  else
444  return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
445  }
446 
447  switch (rf) {
448  case RetFormat::HEX: {
449  // convert hex to bin, continue then with bin part
450  std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable);
451  strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
452  }
453 
454  case RetFormat::BINARY: {
455  try {
456  //deserialize only if user sent a request
457  if (strRequestMutable.size() > 0)
458  {
459  if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA
460  return RESTERR(req, HTTP_BAD_REQUEST, "Combination of URI scheme inputs and raw post data is not allowed");
461 
462  CDataStream oss(SER_NETWORK, PROTOCOL_VERSION);
463  oss << strRequestMutable;
464  oss >> fCheckMemPool;
465  oss >> vOutPoints;
466  }
467  } catch (const std::ios_base::failure&) {
468  // abort in case of unreadable binary data
469  return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
470  }
471  break;
472  }
473 
474  case RetFormat::JSON: {
475  if (!fInputParsed)
476  return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request");
477  break;
478  }
479  default: {
480  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
481  }
482  }
483 
484  // limit max outpoints
485  if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS)
486  return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size()));
487 
488  // check spentness and form a bitmap (as well as a JSON capable human-readable string representation)
489  std::vector<unsigned char> bitmap;
490  std::vector<CCoin> outs;
491  std::string bitmapStringRepresentation;
492  std::vector<bool> hits;
493  bitmap.resize((vOutPoints.size() + 7) / 8);
494  {
495  auto process_utxos = [&vOutPoints, &outs, &hits](const CCoinsView& view, const CTxMemPool& mempool) {
496  for (const COutPoint& vOutPoint : vOutPoints) {
497  Coin coin;
498  bool hit = !mempool.isSpent(vOutPoint) && view.GetCoin(vOutPoint, coin);
499  hits.push_back(hit);
500  if (hit) outs.emplace_back(std::move(coin));
501  }
502  };
503 
504  if (fCheckMemPool) {
505  // use db+mempool as cache backend in case user likes to query mempool
507  CCoinsViewCache& viewChain = *pcoinsTip;
508  CCoinsViewMemPool viewMempool(&viewChain, mempool);
509  process_utxos(viewMempool, mempool);
510  } else {
511  LOCK(cs_main); // no need to lock mempool!
512  process_utxos(*pcoinsTip, CTxMemPool());
513  }
514 
515  for (size_t i = 0; i < hits.size(); ++i) {
516  const bool hit = hits[i];
517  bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output)
518  bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
519  }
520  }
521 
522  switch (rf) {
523  case RetFormat::BINARY: {
524  // serialize data
525  // use exact same output as mentioned in Bip64
526  CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
527  ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
528  std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();
529 
530  req->WriteHeader("Content-Type", "application/octet-stream");
531  req->WriteReply(HTTP_OK, ssGetUTXOResponseString);
532  return true;
533  }
534 
535  case RetFormat::HEX: {
536  CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
537  ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
538  std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n";
539 
540  req->WriteHeader("Content-Type", "text/plain");
541  req->WriteReply(HTTP_OK, strHex);
542  return true;
543  }
544 
545  case RetFormat::JSON: {
546  UniValue objGetUTXOResponse(UniValue::VOBJ);
547 
548  // pack in some essentials
549  // use more or less the same output as mentioned in Bip64
550  objGetUTXOResponse.pushKV("chainHeight", chainActive.Height());
551  objGetUTXOResponse.pushKV("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex());
552  objGetUTXOResponse.pushKV("bitmap", bitmapStringRepresentation);
553 
554  UniValue utxos(UniValue::VARR);
555  for (const CCoin& coin : outs) {
556  UniValue utxo(UniValue::VOBJ);
557  utxo.pushKV("height", (int32_t)coin.nHeight);
558  utxo.pushKV("value", ValueFromAmount(coin.out.nValue));
559 
560  // include the script in a json output
562  ScriptPubKeyToUniv(coin.out.scriptPubKey, o, true);
563  utxo.pushKV("scriptPubKey", o);
564  utxos.push_back(utxo);
565  }
566  objGetUTXOResponse.pushKV("utxos", utxos);
567 
568  // return json string
569  std::string strJSON = objGetUTXOResponse.write() + "\n";
570  req->WriteHeader("Content-Type", "application/json");
571  req->WriteReply(HTTP_OK, strJSON);
572  return true;
573  }
574  default: {
575  return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
576  }
577  }
578 }
579 
580 static const struct {
581  const char* prefix;
582  bool (*handler)(HTTPRequest* req, const std::string& strReq);
583 } uri_prefixes[] = {
584  {"/rest/tx/", rest_tx},
585  {"/rest/block/notxdetails/", rest_block_notxdetails},
586  {"/rest/block/", rest_block_extended},
587  {"/rest/chaininfo", rest_chaininfo},
588  {"/rest/mempool/info", rest_mempool_info},
589  {"/rest/mempool/contents", rest_mempool_contents},
590  {"/rest/headers/", rest_headers},
591  {"/rest/getutxos", rest_getutxos},
592 };
593 
594 void StartREST()
595 {
596  for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
597  RegisterHTTPHandler(uri_prefixes[i].prefix, false, uri_prefixes[i].handler);
598 }
599 
601 {
602 }
603 
604 void StopREST()
605 {
606  for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
607  UnregisterHTTPHandler(uri_prefixes[i].prefix, false);
608 }
uint32_t nHeight
Definition: rest.cpp:46
CAmount nValue
Definition: transaction.h:134
CTxMemPool mempool
bool(* handler)(HTTPRequest *req, const std::string &strReq)
Definition: rest.cpp:582
bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus::Params &consensusParams, uint256 &hashBlock, bool fAllowSlow, CBlockIndex *blockIndex)
Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock...
Definition: validation.cpp:998
CScript scriptPubKey
Definition: transaction.h:135
A UTXO entry.
Definition: coins.h:29
Definition: block.h:74
#define strprintf
Definition: tinyformat.h:1066
UniValue mempoolInfoToJSON()
Mempool information to JSON.
const char * prefix
Definition: rest.cpp:581
CBlockHeader GetBlockHeader() const
Definition: chain.h:279
int Height() const
Return the maximal height in the chain.
Definition: chain.h:476
CTxOut out
unspent transaction output
Definition: coins.h:33
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:88
RetFormat
Definition: rest.cpp:28
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:221
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:402
bool isSpent(const COutPoint &outpoint) const
Definition: txmempool.cpp:337
void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler)
Register handler for prefix.
Definition: httpserver.cpp:642
std::unique_ptr< CCoinsViewCache > pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: validation.cpp:298
uint256 GetBlockHash() const
Definition: chain.h:292
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
Definition: coins.h:39
#define LOCK2(cs1, cs2)
Definition: sync.h:182
CCriticalSection cs_main
Definition: validation.cpp:216
Abstract view on the open txout dataset.
Definition: coins.h:145
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
RetFormat rf
Definition: rest.cpp:36
void WriteReply(int nStatus, const std::string &strReply="")
Write HTTP reply.
Definition: httpserver.cpp:575
UniValue params
Definition: server.h:44
#define LOCK(cs)
Definition: sync.h:181
const char * name
Definition: rest.cpp:37
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:17
UniValue getblockchaininfo(const JSONRPCRequest &request)
Implementation of IsSuperMajority with better feedback.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:463
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:468
bool IsHex(const std::string &str)
void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch)
Unregister handler for prefix.
Definition: httpserver.cpp:648
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
An output of a transaction.
Definition: transaction.h:131
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:18
CCoin()
Definition: rest.cpp:51
CTxOut out
Definition: rest.cpp:47
CCriticalSection cs
Definition: txmempool.h:487
UniValue mempoolToJSON(bool fVerbose)
Mempool to JSON.
Definition: blockchain.cpp:451
void StartREST()
Start HTTP REST subsystem.
Definition: rest.cpp:594
256-bit opaque blob.
Definition: uint256.h:122
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:441
#define ARRAYLEN(array)
void WriteHeader(const std::string &hdr, const std::string &value)
Write output header.
Definition: httpserver.cpp:563
void StopREST()
Stop HTTP REST subsystem.
Definition: rest.cpp:604
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:170
const CChainParams & Params()
Return the currently selected parameters.
bool IsBlockPruned(const CBlockIndex *pblockindex)
Check whether the block associated with this index entry is pruned or not.
Definition: validation.h:498
int RPCSerializationFlags()
Definition: server.cpp:548
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:445
std::string GetHex() const
Definition: uint256.cpp:21
bool RPCIsInWarmup(std::string *outStatus)
Definition: server.cpp:339
Definition: rest.cpp:45
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
Definition: core_write.cpp:153
ADD_SERIALIZE_METHODS
Definition: rest.cpp:49
std::string ReadBody()
Read request body.
Definition: httpserver.cpp:543
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0)
Definition: core_write.cpp:179
In-flight HTTP request.
Definition: httpserver.h:57
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
Definition: core_read.cpp:196
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:600
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:201
CCoin(Coin &&in)
Definition: rest.cpp:52
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:219
#define READWRITE(...)
Definition: serialize.h:173
UniValue blockToJSON(const CBlock &block, const CBlockIndex *blockindex, bool txDetails)
Block description to JSON.
Definition: blockchain.cpp:118
void SetHex(const char *psz)
Definition: uint256.cpp:27
CCoinsView that brings transactions from a mempool into view.
Definition: txmempool.h:715
std::vector< unsigned char > ParseHex(const char *psz)
CBlockIndex * LookupBlockIndex(const uint256 &hash)
Definition: validation.h:431