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