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