From 53b4671a9de75f7c8e2903d510cf88867c3f6b97 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 13:35:44 +0200 Subject: extend conversion to UniValue --- src/rest.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 7c238d506..5f64a0091 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -222,7 +222,7 @@ static bool rest_block(AcceptedConnection* conn, case RF_JSON: { Object objBlock = blockToJSON(block, pblockindex, showTxDetails); - string strJSON = write_string(Value(objBlock), false) + "\n"; + string strJSON = objBlock.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -267,8 +267,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, case RF_JSON: { Array rpcParams; Value chainInfoObject = getblockchaininfo(rpcParams, false); - - string strJSON = write_string(chainInfoObject, false) + "\n"; + string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -319,7 +318,7 @@ static bool rest_tx(AcceptedConnection* conn, case RF_JSON: { Object objTx; TxToJSON(tx, hashBlock, objTx); - string strJSON = write_string(Value(objTx), false) + "\n"; + string strJSON = objTx.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -516,7 +515,7 @@ static bool rest_getutxos(AcceptedConnection* conn, objGetUTXOResponse.push_back(Pair("utxos", utxos)); // return json string - string strJSON = write_string(Value(objGetUTXOResponse), false) + "\n"; + string strJSON = objGetUTXOResponse.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } -- cgit v1.2.3 From 6c7bee062437acbc078533fdcf8e53794031bf99 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 14:48:35 +0200 Subject: expicit set UniValue type to avoid empty values --- src/rest.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 5f64a0091..f3195746b 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -265,7 +265,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, switch (rf) { case RF_JSON: { - Array rpcParams; + UniValue rpcParams(UniValue::VARR); Value chainInfoObject = getblockchaininfo(rpcParams, false); string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; @@ -316,7 +316,7 @@ static bool rest_tx(AcceptedConnection* conn, } case RF_JSON: { - Object objTx; + UniValue objTx(UniValue::VOBJ); TxToJSON(tx, hashBlock, objTx); string strJSON = objTx.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; @@ -491,7 +491,7 @@ static bool rest_getutxos(AcceptedConnection* conn, } case RF_JSON: { - Object objGetUTXOResponse; + UniValue objGetUTXOResponse(UniValue::VOBJ); // pack in some essentials // use more or less the same output as mentioned in Bip64 @@ -499,15 +499,15 @@ static bool rest_getutxos(AcceptedConnection* conn, objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex())); objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation)); - Array utxos; + UniValue utxos(UniValue::VARR); BOOST_FOREACH (const CCoin& coin, outs) { - Object utxo; + UniValue utxo(UniValue::VOBJ); utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer)); utxo.push_back(Pair("height", (int32_t)coin.nHeight)); utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue))); // include the script in a json output - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true); utxo.push_back(Pair("scriptPubKey", o)); utxos.push_back(utxo); -- cgit v1.2.3 From 3df0411ad9fd75fb27af53e44835d41f5480fe3f Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 13 May 2015 21:29:19 +0200 Subject: remove JSON Spirit UniValue wrapper --- src/rest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index f3195746b..3142b2503 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -62,7 +62,7 @@ public: }; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); -extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); static RestErr RESTERR(enum HTTPStatusCode status, string message) @@ -221,7 +221,7 @@ static bool rest_block(AcceptedConnection* conn, } case RF_JSON: { - Object objBlock = blockToJSON(block, pblockindex, showTxDetails); + UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails); string strJSON = objBlock.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; @@ -266,7 +266,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, switch (rf) { case RF_JSON: { UniValue rpcParams(UniValue::VARR); - Value chainInfoObject = getblockchaininfo(rpcParams, false); + UniValue chainInfoObject = getblockchaininfo(rpcParams, false); string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; -- cgit v1.2.3 From 9a8897f4ac992741e153d88b54bd2cde877c713d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 18 May 2015 14:02:18 +0200 Subject: Remove JSON Spirit wrapper, remove JSON Spirit leftovers - implement find_value() function for UniValue - replace all Array/Value/Object types with UniValues, remove JSON Spirit to UniValue wrapper - remove JSON Spirit sources --- src/rest.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 3142b2503..1fce7dfc9 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -16,8 +16,9 @@ #include #include +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; static const int MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once @@ -61,9 +62,9 @@ public: string message; }; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); -extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); +extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); static RestErr RESTERR(enum HTTPStatusCode status, string message) { -- cgit v1.2.3 From e617fe25785bfba30bcb0a8d8af6797b44ba07f5 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 13 May 2015 20:04:39 +0000 Subject: Fix various warnings Found while building on Debian 7 --- src/rest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 7c238d506..5af9d5c79 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -19,7 +19,7 @@ using namespace std; using namespace json_spirit; -static const int MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once +static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once enum RetFormat { RF_UNDEF, -- cgit v1.2.3 From c45c7ea0fa38fda453c596bd3161c9362d689381 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 16 Dec 2014 10:50:44 +0100 Subject: [REST] add JSON support for /rest/headers/ --- src/rest.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index a1bd893be..dfe01495f 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -65,6 +65,7 @@ public: extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); +extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); static RestErr RESTERR(enum HTTPStatusCode status, string message) { @@ -134,14 +135,14 @@ static bool rest_headers(AcceptedConnection* conn, if (!ParseHashStr(hashStr, hash)) throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); - std::vector headers; + std::vector headers; headers.reserve(count); { LOCK(cs_main); BlockMap::const_iterator it = mapBlockIndex.find(hash); const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL; while (pindex != NULL && chainActive.Contains(pindex)) { - headers.push_back(pindex->GetBlockHeader()); + headers.push_back(pindex); if (headers.size() == (unsigned long)count) break; pindex = chainActive.Next(pindex); @@ -149,8 +150,8 @@ static bool rest_headers(AcceptedConnection* conn, } CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); - BOOST_FOREACH(const CBlockHeader &header, headers) { - ssHeader << header; + BOOST_FOREACH(const CBlockIndex *pindex, headers) { + ssHeader << pindex->GetBlockHeader(); } switch (rf) { @@ -166,6 +167,16 @@ static bool rest_headers(AcceptedConnection* conn, return true; } + case RF_JSON: { + UniValue jsonHeaders(UniValue::VARR); + BOOST_FOREACH(const CBlockIndex *pindex, headers) { + jsonHeaders.push_back(blockheaderToJSON(pindex)); + } + string strJSON = jsonHeaders.write() + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + return true; + } + default: { throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); } -- cgit v1.2.3 From 9dd793f499254600efa468938cef9baa28ac81b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Sun, 5 Jul 2015 14:17:46 +0200 Subject: TRIVIAL: Missing includes --- src/rest.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index dfe01495f..0dd238b68 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "chain.h" #include "primitives/block.h" #include "primitives/transaction.h" #include "main.h" -- cgit v1.2.3 From 70180b2e576ebcb675c905ef4bd9d5b4fd378b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Thu, 6 Aug 2015 19:38:19 +0200 Subject: Implement REST mempool API, add test and documentation. --- src/rest.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 0dd238b68..74d27e73b 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -65,6 +65,8 @@ public: extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern UniValue mempoolInfoToJSON(); +extern UniValue mempoolToJSON(bool fVerbose = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); @@ -293,6 +295,58 @@ static bool rest_chaininfo(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } +static bool rest_mempool_info(AcceptedConnection* conn, + const std::string& strURIPart, + const std::string& strRequest, + const std::map& mapHeaders, + bool fRun) +{ + vector params; + const RetFormat rf = ParseDataFormat(params, strURIPart); + + switch (rf) { + case RF_JSON: { + UniValue mempoolInfoObject = mempoolInfoToJSON(); + + string strJSON = mempoolInfoObject.write() + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + return true; + } + default: { + throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + +static bool rest_mempool_contents(AcceptedConnection* conn, + const std::string& strURIPart, + const std::string& strRequest, + const std::map& mapHeaders, + bool fRun) +{ + vector params; + const RetFormat rf = ParseDataFormat(params, strURIPart); + + switch (rf) { + case RF_JSON: { + UniValue mempoolObject = mempoolToJSON(true); + + string strJSON = mempoolObject.write() + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + return true; + } + default: { + throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + static bool rest_tx(AcceptedConnection* conn, const std::string& strURIPart, const std::string& strRequest, @@ -553,6 +607,8 @@ static const struct { {"/rest/block/notxdetails/", rest_block_notxdetails}, {"/rest/block/", rest_block_extended}, {"/rest/chaininfo", rest_chaininfo}, + {"/rest/mempool/info", rest_mempool_info}, + {"/rest/mempool/contents", rest_mempool_contents}, {"/rest/headers/", rest_headers}, {"/rest/getutxos", rest_getutxos}, }; -- cgit v1.2.3 From 40b556d3742a1f65d67e2d4c760d0b13fe8be5b7 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 23 Jan 2015 07:53:17 +0100 Subject: evhttpd implementation - *Replace usage of boost::asio with [libevent2](http://libevent.org/)*. boost::asio is not part of C++11, so unlike other boost there is no forwards-compatibility reason to stick with it. Together with #4738 (convert json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with regard to compile-time slowness. - *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling is handled by libevent, a work queue (with configurable depth and parallelism) is used to handle application requests. - *Wrap HTTP request in C++ class*; this makes the application code mostly HTTP-server-neutral - *Refactor RPC to move all http-specific code to a separate file*. Theoreticaly this can allow building without HTTP server but with another RPC backend, e.g. Qt's debug console (currently not implemented) or future RPC mechanisms people may want to use. - *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL paths they want to handle. By using a proven, high-performance asynchronous networking library (also used by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided. What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests pass. The aim for now is everything but SSL support. Configuration options: - `-rpcthreads`: repurposed as "number of work handler threads". Still defaults to 4. - `-rpcworkqueue`: maximum depth of work queue. When this is reached, new requests will return a 500 Internal Error. - `-rpctimeout`: inactivity time, in seconds, after which to disconnect a client. - `-debug=http`: low-level http activity logging --- src/rest.cpp | 243 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 111 insertions(+), 132 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 74d27e73b..940526706 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -7,6 +7,7 @@ #include "primitives/block.h" #include "primitives/transaction.h" #include "main.h" +#include "httpserver.h" #include "rpcserver.h" #include "streams.h" #include "sync.h" @@ -56,13 +57,6 @@ struct CCoin { } }; -class RestErr -{ -public: - enum HTTPStatusCode status; - string message; -}; - extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); extern UniValue mempoolInfoToJSON(); @@ -70,15 +64,14 @@ extern UniValue mempoolToJSON(bool fVerbose = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); -static RestErr RESTERR(enum HTTPStatusCode status, string message) +static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, string message) { - RestErr re; - re.status = status; - re.message = message; - return re; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(status, message + "\r\n"); + return false; } -static enum RetFormat ParseDataFormat(vector& params, const string strReq) +static enum RetFormat ParseDataFormat(vector& params, const string& strReq) { boost::split(params, strReq, boost::is_any_of(".")); if (params.size() > 1) { @@ -115,28 +108,35 @@ static bool ParseHashStr(const string& strReq, uint256& v) return true; } -static bool rest_headers(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun) +static bool CheckWarmup(HTTPRequest* req) +{ + std::string statusmessage; + if (RPCIsInWarmup(&statusmessage)) + return RESTERR(req, HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage); + return true; +} + +static bool rest_headers(HTTPRequest* req, + const std::string& strURIPart) { + if (!CheckWarmup(req)) + return false; vector params; const RetFormat rf = ParseDataFormat(params, strURIPart); vector path; boost::split(path, params[0], boost::is_any_of("/")); if (path.size() != 2) - throw RESTERR(HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers//.."); + return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers//.."); long count = strtol(path[0].c_str(), NULL, 10); if (count < 1 || count > 2000) - throw RESTERR(HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); + return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); string hashStr = path[1]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); std::vector headers; headers.reserve(count); @@ -160,28 +160,29 @@ static bool rest_headers(AcceptedConnection* conn, switch (rf) { case RF_BINARY: { string binaryHeader = ssHeader.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryHeader.size(), "application/octet-stream") << binaryHeader << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryHeader); return true; } case RF_HEX: { string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } - case RF_JSON: { UniValue jsonHeaders(UniValue::VARR); BOOST_FOREACH(const CBlockIndex *pindex, headers) { jsonHeaders.push_back(blockheaderToJSON(pindex)); } string strJSON = jsonHeaders.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } - default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); } } @@ -189,34 +190,33 @@ static bool rest_headers(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_block(AcceptedConnection* conn, +static bool rest_block(HTTPRequest* req, const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun, bool showTxDetails) { + if (!CheckWarmup(req)) + return false; vector params; const RetFormat rf = ParseDataFormat(params, strURIPart); string hashStr = params[0]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CBlock block; CBlockIndex* pblockindex = NULL; { LOCK(cs_main); if (mapBlockIndex.count(hash) == 0) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); pblockindex = mapBlockIndex[hash]; if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); if (!ReadBlockFromDisk(block, pblockindex)) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); @@ -225,25 +225,28 @@ static bool rest_block(AcceptedConnection* conn, switch (rf) { case RF_BINARY: { string binaryBlock = ssBlock.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryBlock.size(), "application/octet-stream") << binaryBlock << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryBlock); return true; } case RF_HEX: { string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } case RF_JSON: { UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails); string strJSON = objBlock.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } @@ -251,30 +254,20 @@ static bool rest_block(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_block_extended(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun) +static bool rest_block_extended(HTTPRequest* req, const std::string& strURIPart) { - return rest_block(conn, strURIPart, strRequest, mapHeaders, fRun, true); + return rest_block(req, strURIPart, true); } -static bool rest_block_notxdetails(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun) +static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPart) { - return rest_block(conn, strURIPart, strRequest, mapHeaders, fRun, false); + return rest_block(req, strURIPart, false); } -static bool rest_chaininfo(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun) +static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) { + if (!CheckWarmup(req)) + return false; vector params; const RetFormat rf = ParseDataFormat(params, strURIPart); @@ -283,11 +276,12 @@ static bool rest_chaininfo(AcceptedConnection* conn, UniValue rpcParams(UniValue::VARR); UniValue chainInfoObject = getblockchaininfo(rpcParams, false); string strJSON = chainInfoObject.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); } } @@ -295,12 +289,10 @@ static bool rest_chaininfo(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_mempool_info(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun) +static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart) { + if (!CheckWarmup(req)) + return false; vector params; const RetFormat rf = ParseDataFormat(params, strURIPart); @@ -309,11 +301,12 @@ static bool rest_mempool_info(AcceptedConnection* conn, UniValue mempoolInfoObject = mempoolInfoToJSON(); string strJSON = mempoolInfoObject.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); } } @@ -321,12 +314,10 @@ static bool rest_mempool_info(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_mempool_contents(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun) +static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart) { + if (!CheckWarmup(req)) + return false; vector params; const RetFormat rf = ParseDataFormat(params, strURIPart); @@ -335,11 +326,12 @@ static bool rest_mempool_contents(AcceptedConnection* conn, UniValue mempoolObject = mempoolToJSON(true); string strJSON = mempoolObject.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)"); } } @@ -347,24 +339,22 @@ static bool rest_mempool_contents(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_tx(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun) +static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) { + if (!CheckWarmup(req)) + return false; vector params; const RetFormat rf = ParseDataFormat(params, strURIPart); string hashStr = params[0]; uint256 hash; if (!ParseHashStr(hashStr, hash)) - throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CTransaction tx; uint256 hashBlock = uint256(); if (!GetTransaction(hash, tx, hashBlock, true)) - throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); ssTx << tx; @@ -372,13 +362,15 @@ static bool rest_tx(AcceptedConnection* conn, switch (rf) { case RF_BINARY: { string binaryTx = ssTx.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryTx.size(), "application/octet-stream") << binaryTx << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, binaryTx); return true; } case RF_HEX: { string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } @@ -386,12 +378,13 @@ static bool rest_tx(AcceptedConnection* conn, UniValue objTx(UniValue::VOBJ); TxToJSON(tx, hashBlock, objTx); string strJSON = objTx.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } @@ -399,12 +392,10 @@ static bool rest_tx(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } -static bool rest_getutxos(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun) +static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) { + if (!CheckWarmup(req)) + return false; vector params; enum RetFormat rf = ParseDataFormat(params, strURIPart); @@ -416,8 +407,9 @@ static bool rest_getutxos(AcceptedConnection* conn, } // throw exception in case of a empty request - if (strRequest.length() == 0 && uriParts.size() == 0) - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + std::string strRequestMutable = req->ReadBody(); + if (strRequestMutable.length() == 0 && uriParts.size() == 0) + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); bool fInputParsed = false; bool fCheckMemPool = false; @@ -441,7 +433,7 @@ static bool rest_getutxos(AcceptedConnection* conn, std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1); if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid)) - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); txid.SetHex(strTxid); vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput)); @@ -450,15 +442,13 @@ static bool rest_getutxos(AcceptedConnection* conn, if (vOutPoints.size() > 0) fInputParsed = true; else - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); } - string strRequestMutable = strRequest; //convert const string to string for allowing hex to bin converting - switch (rf) { case RF_HEX: { // convert hex to bin, continue then with bin part - std::vector strRequestV = ParseHex(strRequest); + std::vector strRequestV = ParseHex(strRequestMutable); strRequestMutable.assign(strRequestV.begin(), strRequestV.end()); } @@ -468,7 +458,7 @@ static bool rest_getutxos(AcceptedConnection* conn, if (strRequestMutable.size() > 0) { if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed"); CDataStream oss(SER_NETWORK, PROTOCOL_VERSION); oss << strRequestMutable; @@ -477,24 +467,24 @@ static bool rest_getutxos(AcceptedConnection* conn, } } catch (const std::ios_base::failure& e) { // abort in case of unreadable binary data - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); } break; } case RF_JSON: { if (!fInputParsed) - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); break; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } // limit max outpoints if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) - throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); + return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); // check spentness and form a bitmap (as well as a JSON capable human-readble string representation) vector bitmap; @@ -544,7 +534,8 @@ static bool rest_getutxos(AcceptedConnection* conn, ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; string ssGetUTXOResponseString = ssGetUTXOResponse.str(); - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, ssGetUTXOResponseString.size(), "application/octet-stream") << ssGetUTXOResponseString << std::flush; + req->WriteHeader("Content-Type", "application/octet-stream"); + req->WriteReply(HTTP_OK, ssGetUTXOResponseString); return true; } @@ -553,7 +544,8 @@ static bool rest_getutxos(AcceptedConnection* conn, ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; + req->WriteHeader("Content-Type", "text/plain"); + req->WriteReply(HTTP_OK, strHex); return true; } @@ -583,11 +575,12 @@ static bool rest_getutxos(AcceptedConnection* conn, // return json string string strJSON = objGetUTXOResponse.write() + "\n"; - conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + req->WriteHeader("Content-Type", "application/json"); + req->WriteReply(HTTP_OK, strJSON); return true; } default: { - throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); } } @@ -597,11 +590,7 @@ static bool rest_getutxos(AcceptedConnection* conn, static const struct { const char* prefix; - bool (*handler)(AcceptedConnection* conn, - const std::string& strURIPart, - const std::string& strRequest, - const std::map& mapHeaders, - bool fRun); + bool (*handler)(HTTPRequest* req, const std::string& strReq); } uri_prefixes[] = { {"/rest/tx/", rest_tx}, {"/rest/block/notxdetails/", rest_block_notxdetails}, @@ -613,29 +602,19 @@ static const struct { {"/rest/getutxos", rest_getutxos}, }; -bool HTTPReq_REST(AcceptedConnection* conn, - const std::string& strURI, - const string& strRequest, - const std::map& mapHeaders, - bool fRun) +bool StartREST() { - try { - std::string statusmessage; - if (RPCIsInWarmup(&statusmessage)) - throw RESTERR(HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage); - - for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) { - unsigned int plen = strlen(uri_prefixes[i].prefix); - if (strURI.substr(0, plen) == uri_prefixes[i].prefix) { - string strURIPart = strURI.substr(plen); - return uri_prefixes[i].handler(conn, strURIPart, strRequest, mapHeaders, fRun); - } - } - } catch (const RestErr& re) { - conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush; - return false; - } + for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) + RegisterHTTPHandler(uri_prefixes[i].prefix, false, uri_prefixes[i].handler); + return true; +} - conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush; - return false; +void InterruptREST() +{ +} + +void StopREST() +{ + for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) + UnregisterHTTPHandler(uri_prefixes[i].prefix, false); } -- cgit v1.2.3 From 9cdc3353c5cb30b6aedf04ea8bdff9135751d72d Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Mon, 7 Sep 2015 20:38:03 +0200 Subject: Simplify logic of REST request suffix parsing. This patch changes the way the suffix (giving the requested data format) is parsed for REST requests. Before, the string was split at '.' characters and it was assumed that the second part was the suffix. Now, we look for the last dot and use that to determine the suffix. This allows for strings that contain dots (not used now, though), and seems, in general, to be clearer and more intuitive. --- src/rest.cpp | 57 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 25 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 940526706..226e237fc 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -71,15 +71,24 @@ static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, string message return false; } -static enum RetFormat ParseDataFormat(vector& params, const string& strReq) +static enum RetFormat ParseDataFormat(std::string& param, const std::string& strReq) { - boost::split(params, strReq, boost::is_any_of(".")); - if (params.size() > 1) { - for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) - if (params[1] == rf_names[i].name) - return rf_names[i].rf; + const std::string::size_type pos = strReq.rfind('.'); + if (pos == std::string::npos) + { + param = strReq; + return rf_names[0].rf; } + param = strReq.substr(0, pos); + const std::string suff(strReq, pos + 1); + + for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) + if (suff == rf_names[i].name) + return rf_names[i].rf; + + /* If no suffix is found, return original string. */ + param = strReq; return rf_names[0].rf; } @@ -121,10 +130,10 @@ static bool rest_headers(HTTPRequest* req, { if (!CheckWarmup(req)) return false; - vector params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); vector path; - boost::split(path, params[0], boost::is_any_of("/")); + boost::split(path, param, boost::is_any_of("/")); if (path.size() != 2) return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers//.."); @@ -196,10 +205,9 @@ static bool rest_block(HTTPRequest* req, { if (!CheckWarmup(req)) return false; - vector params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + std::string hashStr; + const RetFormat rf = ParseDataFormat(hashStr, strURIPart); - string hashStr = params[0]; uint256 hash; if (!ParseHashStr(hashStr, hash)) return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); @@ -268,8 +276,8 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; - vector params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); switch (rf) { case RF_JSON: { @@ -293,8 +301,8 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; - vector params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); switch (rf) { case RF_JSON: { @@ -318,8 +326,8 @@ static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPar { if (!CheckWarmup(req)) return false; - vector params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); switch (rf) { case RF_JSON: { @@ -343,10 +351,9 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; - vector params; - const RetFormat rf = ParseDataFormat(params, strURIPart); + std::string hashStr; + const RetFormat rf = ParseDataFormat(hashStr, strURIPart); - string hashStr = params[0]; uint256 hash; if (!ParseHashStr(hashStr, hash)) return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); @@ -396,13 +403,13 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) return false; - vector params; - enum RetFormat rf = ParseDataFormat(params, strURIPart); + std::string param; + const RetFormat rf = ParseDataFormat(param, strURIPart); vector uriParts; - if (params.size() > 0 && params[0].length() > 1) + if (param.length() > 1) { - std::string strUriParams = params[0].substr(1); + std::string strUriParams = param.substr(1); boost::split(uriParts, strUriParams, boost::is_any_of("/")); } -- cgit v1.2.3 From 9623e934732ba0f0a5176cd3d993ebcda327b413 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 4 Sep 2015 16:11:34 +0200 Subject: [Univalue] add univalue over subtree similar to secp256k1 include and compile univalue over a subtree --- src/rest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 226e237fc..c46d7a8bd 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -18,7 +18,7 @@ #include #include -#include "univalue/univalue.h" +#include using namespace std; -- cgit v1.2.3 From 87cbdb8b41eee4067023cfa0d9d68722da74a5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Fri, 17 Apr 2015 14:19:21 +0200 Subject: Globals: Explicit Consensus::Params arg for main: -CheckBlockIndex -DisconnectTip -GetTransaction -InvalidateBlock -ProcessGetData -ReadBlockFromDisk --- src/rest.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index c46d7a8bd..5d69542a9 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chain.h" +#include "chainparams.h" #include "primitives/block.h" #include "primitives/transaction.h" #include "main.h" @@ -223,7 +224,7 @@ static bool rest_block(HTTPRequest* req, if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex)) + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } @@ -360,7 +361,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) CTransaction tx; uint256 hashBlock = uint256(); - if (!GetTransaction(hash, tx, hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); -- cgit v1.2.3 From 8a03727d9cc975a3d0843d83ef05957b9e9fbbca Mon Sep 17 00:00:00 2001 From: paveljanik Date: Fri, 3 Jul 2015 16:36:49 +0200 Subject: Fix various typos --- src/rest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 5d69542a9..2ad7bc106 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -494,7 +494,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); - // check spentness and form a bitmap (as well as a JSON capable human-readble string representation) + // check spentness and form a bitmap (as well as a JSON capable human-readable string representation) vector bitmap; vector outs; std::string bitmapStringRepresentation; -- cgit v1.2.3 From fa24439ff3d8ab5b9efaf66ef4dae6713b88cb35 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 13 Dec 2015 17:58:29 +0100 Subject: Bump copyright headers to 2015 --- src/rest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 2ad7bc106..ad884dac1 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From a0eaff8a1d18ebba33cdea4cd1efaddeb55519e7 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 15 Jan 2016 11:55:17 +1100 Subject: move rpc* to rpc/ --- src/rest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index ad884dac1..ebdccc940 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -9,7 +9,7 @@ #include "primitives/transaction.h" #include "main.h" #include "httpserver.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "streams.h" #include "sync.h" #include "txmempool.h" -- cgit v1.2.3 From fb8a8cf2e610920e9eee61c19ed6080af064bb43 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 29 Mar 2016 19:43:02 +0200 Subject: rpc: Register calls where they are defined Split out methods to every module, apart from 'help' and 'stop' which are implemented in rpcserver.cpp itself. - This makes it easier to add or remove RPC commands - no longer everything that includes rpcserver.h has to be rebuilt when there's a change there. - Cleans up `rpc/server.h` by getting rid of the huge cluttered list of function definitions. - Removes most of the bitcoin-specific code from rpcserver.cpp and .h. Continues #7307 for the non-wallet. --- src/rest.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index ebdccc940..2dff8d7da 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -273,6 +273,9 @@ static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPa return rest_block(req, strURIPart, false); } +// A bit of a hack - dependency on a function defined in rpc/blockchain.cpp +UniValue getblockchaininfo(const UniValue& params, bool fHelp); + static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) { if (!CheckWarmup(req)) -- cgit v1.2.3 From f012a857f5e9b3bdd11a64dd0c16b4c805076594 Mon Sep 17 00:00:00 2001 From: djpnewton Date: Thu, 1 Sep 2016 11:52:47 +1200 Subject: rest.cpp: change HTTP_INTERNAL_SERVER_ERROR to HTTP_BAD_REQUEST --- src/rest.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 2dff8d7da..c81559212 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -420,7 +420,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) // throw exception in case of a empty request std::string strRequestMutable = req->ReadBody(); if (strRequestMutable.length() == 0 && uriParts.size() == 0) - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); bool fInputParsed = false; bool fCheckMemPool = false; @@ -444,7 +444,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1); if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid)) - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + return RESTERR(req, HTTP_BAD_REQUEST, "Parse error"); txid.SetHex(strTxid); vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput)); @@ -453,7 +453,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) if (vOutPoints.size() > 0) fInputParsed = true; else - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); } switch (rf) { @@ -469,7 +469,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) if (strRequestMutable.size() > 0) { if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed"); + return RESTERR(req, HTTP_BAD_REQUEST, "Combination of URI scheme inputs and raw post data is not allowed"); CDataStream oss(SER_NETWORK, PROTOCOL_VERSION); oss << strRequestMutable; @@ -478,14 +478,14 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) } } catch (const std::ios_base::failure& e) { // abort in case of unreadable binary data - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + return RESTERR(req, HTTP_BAD_REQUEST, "Parse error"); } break; } case RF_JSON: { if (!fInputParsed) - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); break; } default: { @@ -495,7 +495,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) // limit max outpoints if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); + return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); // check spentness and form a bitmap (as well as a JSON capable human-readable string representation) vector bitmap; -- cgit v1.2.3 From 69d1c25768a8649bfc7eb8e9c35b8fe9874ac9fc Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 22 Sep 2016 09:46:41 +0200 Subject: [RPC] Give RPC commands more information about the RPC request --- src/rest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index c81559212..707dfe698 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -274,7 +274,7 @@ static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPa } // A bit of a hack - dependency on a function defined in rpc/blockchain.cpp -UniValue getblockchaininfo(const UniValue& params, bool fHelp); +UniValue getblockchaininfo(const JSONRPCRequest& request); static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) { @@ -285,8 +285,8 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) switch (rf) { case RF_JSON: { - UniValue rpcParams(UniValue::VARR); - UniValue chainInfoObject = getblockchaininfo(rpcParams, false); + JSONRPCRequest jsonRequest; + UniValue chainInfoObject = getblockchaininfo(jsonRequest); string strJSON = chainInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); -- cgit v1.2.3 From e7156ad61be2fe935fdb64e9d0e877fa0e9f7f9e Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 22 Sep 2016 09:58:13 +0200 Subject: [RPC] pass HTTP basic authentication username to the JSONRequest object --- src/rest.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 707dfe698..b8b542062 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -286,6 +286,7 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) switch (rf) { case RF_JSON: { JSONRPCRequest jsonRequest; + jsonRequest.params = UniValue(UniValue::VARR); UniValue chainInfoObject = getblockchaininfo(jsonRequest); string strJSON = chainInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); -- cgit v1.2.3 From 528472111b4965b1a99c4bcf08ac5ec93d87f10f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 28 Oct 2016 16:29:17 -0700 Subject: Get rid of nType and nVersion Remove the nType and nVersion as parameters to all serialization methods and functions. There is only one place where it's read and has an impact (in CAddress), and even there it does not impact any of the recursively invoked serializers. Instead, the few places that need nType or nVersion are changed to read it directly from the stream object, through GetType() and GetVersion() methods which are added to all stream classes. --- src/rest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index b8b542062..90cca6f48 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -50,7 +50,7 @@ struct CCoin { ADD_SERIALIZE_METHODS; template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nTxVer); READWRITE(nHeight); -- cgit v1.2.3 From 76faa3cdfedbd3fc91be4ecfff77fc6dc18134fb Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 1 Dec 2016 16:06:41 -0800 Subject: Rename the remaining main.{h,cpp} to validation.{h,cpp} --- src/rest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 90cca6f48..7d7a7d322 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -7,7 +7,7 @@ #include "chainparams.h" #include "primitives/block.h" #include "primitives/transaction.h" -#include "main.h" +#include "validation.h" #include "httpserver.h" #include "rpc/server.h" #include "streams.h" -- cgit v1.2.3 From a1883536b455b889f1ebfca9e50d1e0ef28a7731 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 11 Nov 2016 16:30:38 -0800 Subject: Switch GetTransaction to returning a CTransactionRef --- src/rest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 7d7a7d322..6379061f8 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -363,7 +363,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) if (!ParseHashStr(hashStr, hash)) return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); - CTransaction tx; + CTransactionRef tx; uint256 hashBlock = uint256(); if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); @@ -388,7 +388,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) case RF_JSON: { UniValue objTx(UniValue::VOBJ); - TxToJSON(tx, hashBlock, objTx); + TxToJSON(*tx, hashBlock, objTx); string strJSON = objTx.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); -- cgit v1.2.3 From 412bab22b23036962509d2655b68cccd726b6ba4 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Tue, 22 Nov 2016 15:47:07 -0500 Subject: Adapt ZMQ/rest serialization to take rpcserialversion arg --- src/rest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 6379061f8..6b6b7401f 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -228,7 +228,7 @@ static bool rest_block(HTTPRequest* req, return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; switch (rf) { @@ -368,7 +368,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssTx << tx; switch (rf) { -- cgit v1.2.3 From 27765b6403cece54320374b37afb01a0cfe571c3 Mon Sep 17 00:00:00 2001 From: isle2983 Date: Sat, 31 Dec 2016 11:01:21 -0700 Subject: Increment MIT Licence copyright header year on files modified in 2016 Edited via: $ contrib/devtools/copyright_header.py update . --- src/rest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 6b6b7401f..8a7c985e7 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -- cgit v1.2.3 From 82e8baab3caaadb1d923d1332c577fb91b9c5747 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 12 Jan 2017 12:06:32 -0800 Subject: Avoid boost dynamic_bitset in rest_getutxos --- src/rest.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 8a7c985e7..a8f8e753c 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -17,7 +17,6 @@ #include "version.h" #include -#include #include @@ -502,7 +501,8 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) vector bitmap; vector outs; std::string bitmapStringRepresentation; - boost::dynamic_bitset hits(vOutPoints.size()); + std::vector hits; + bitmap.resize((vOutPoints.size() + 7) / 8); { LOCK2(cs_main, mempool.cs); @@ -518,10 +518,11 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) for (size_t i = 0; i < vOutPoints.size(); i++) { CCoins coins; uint256 hash = vOutPoints[i].hash; + bool hit = false; if (view.GetCoins(hash, coins)) { mempool.pruneSpent(hash, coins); if (coins.IsAvailable(vOutPoints[i].n)) { - hits[i] = true; + hit = true; // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if // n is valid but points to an already spent output (IsNull). CCoin coin; @@ -533,10 +534,11 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) } } - bitmapStringRepresentation.append(hits[i] ? "1" : "0"); // form a binary string representation (human-readable for json output) + hits.push_back(hit); + bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output) + bitmap[i / 8] |= ((uint8_t)hit) << (i % 8); } } - boost::to_block_range(hits, std::back_inserter(bitmap)); switch (rf) { case RF_BINARY: { -- cgit v1.2.3 From b7b48c8bbdf7a90861610b035d8b0a247ef78c45 Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Fri, 27 Jan 2017 17:43:41 +0900 Subject: Refactor: Remove using namespace from src/*.cpp. --- src/rest.cpp | 52 +++++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 27 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index a8f8e753c..54eefcafe 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -20,8 +20,6 @@ #include -using namespace std; - static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once enum RetFormat { @@ -64,7 +62,7 @@ extern UniValue mempoolToJSON(bool fVerbose = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); -static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, string message) +static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string message) { req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(status, message + "\r\n"); @@ -92,9 +90,9 @@ static enum RetFormat ParseDataFormat(std::string& param, const std::string& str return rf_names[0].rf; } -static string AvailableDataFormatsString() +static std::string AvailableDataFormatsString() { - string formats = ""; + std::string formats = ""; for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) if (strlen(rf_names[i].name) > 0) { formats.append("."); @@ -108,7 +106,7 @@ static string AvailableDataFormatsString() return formats; } -static bool ParseHashStr(const string& strReq, uint256& v) +static bool ParseHashStr(const std::string& strReq, uint256& v) { if (!IsHex(strReq) || (strReq.size() != 64)) return false; @@ -132,7 +130,7 @@ static bool rest_headers(HTTPRequest* req, return false; std::string param; const RetFormat rf = ParseDataFormat(param, strURIPart); - vector path; + std::vector path; boost::split(path, param, boost::is_any_of("/")); if (path.size() != 2) @@ -142,7 +140,7 @@ static bool rest_headers(HTTPRequest* req, if (count < 1 || count > 2000) return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); - string hashStr = path[1]; + std::string hashStr = path[1]; uint256 hash; if (!ParseHashStr(hashStr, hash)) return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); @@ -168,14 +166,14 @@ static bool rest_headers(HTTPRequest* req, switch (rf) { case RF_BINARY: { - string binaryHeader = ssHeader.str(); + std::string binaryHeader = ssHeader.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryHeader); return true; } case RF_HEX: { - string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; + std::string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; @@ -185,7 +183,7 @@ static bool rest_headers(HTTPRequest* req, BOOST_FOREACH(const CBlockIndex *pindex, headers) { jsonHeaders.push_back(blockheaderToJSON(pindex)); } - string strJSON = jsonHeaders.write() + "\n"; + std::string strJSON = jsonHeaders.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -232,14 +230,14 @@ static bool rest_block(HTTPRequest* req, switch (rf) { case RF_BINARY: { - string binaryBlock = ssBlock.str(); + std::string binaryBlock = ssBlock.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryBlock); return true; } case RF_HEX: { - string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; @@ -247,7 +245,7 @@ static bool rest_block(HTTPRequest* req, case RF_JSON: { UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails); - string strJSON = objBlock.write() + "\n"; + std::string strJSON = objBlock.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -287,7 +285,7 @@ static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart) JSONRPCRequest jsonRequest; jsonRequest.params = UniValue(UniValue::VARR); UniValue chainInfoObject = getblockchaininfo(jsonRequest); - string strJSON = chainInfoObject.write() + "\n"; + std::string strJSON = chainInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -312,7 +310,7 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart) case RF_JSON: { UniValue mempoolInfoObject = mempoolInfoToJSON(); - string strJSON = mempoolInfoObject.write() + "\n"; + std::string strJSON = mempoolInfoObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -337,7 +335,7 @@ static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPar case RF_JSON: { UniValue mempoolObject = mempoolToJSON(true); - string strJSON = mempoolObject.write() + "\n"; + std::string strJSON = mempoolObject.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -372,14 +370,14 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) switch (rf) { case RF_BINARY: { - string binaryTx = ssTx.str(); + std::string binaryTx = ssTx.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, binaryTx); return true; } case RF_HEX: { - string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; + std::string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); return true; @@ -388,7 +386,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) case RF_JSON: { UniValue objTx(UniValue::VOBJ); TxToJSON(*tx, hashBlock, objTx); - string strJSON = objTx.write() + "\n"; + std::string strJSON = objTx.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; @@ -410,7 +408,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) std::string param; const RetFormat rf = ParseDataFormat(param, strURIPart); - vector uriParts; + std::vector uriParts; if (param.length() > 1) { std::string strUriParams = param.substr(1); @@ -424,7 +422,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) bool fInputParsed = false; bool fCheckMemPool = false; - vector vOutPoints; + std::vector vOutPoints; // parse/deserialize input // input-format = output-format, rest/getutxos/bin requires binary input, gives binary output, ... @@ -498,8 +496,8 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); // check spentness and form a bitmap (as well as a JSON capable human-readable string representation) - vector bitmap; - vector outs; + std::vector bitmap; + std::vector outs; std::string bitmapStringRepresentation; std::vector hits; bitmap.resize((vOutPoints.size() + 7) / 8); @@ -546,7 +544,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) // use exact same output as mentioned in Bip64 CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; - string ssGetUTXOResponseString = ssGetUTXOResponse.str(); + std::string ssGetUTXOResponseString = ssGetUTXOResponse.str(); req->WriteHeader("Content-Type", "application/octet-stream"); req->WriteReply(HTTP_OK, ssGetUTXOResponseString); @@ -556,7 +554,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) case RF_HEX: { CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION); ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs; - string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; + std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n"; req->WriteHeader("Content-Type", "text/plain"); req->WriteReply(HTTP_OK, strHex); @@ -588,7 +586,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) objGetUTXOResponse.push_back(Pair("utxos", utxos)); // return json string - string strJSON = objGetUTXOResponse.write() + "\n"; + std::string strJSON = objGetUTXOResponse.write() + "\n"; req->WriteHeader("Content-Type", "application/json"); req->WriteReply(HTTP_OK, strJSON); return true; -- cgit v1.2.3 From bc8cca48968dfa3f60b5eae6a2b92bdd2870eee3 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Sun, 13 Aug 2017 13:31:12 +0100 Subject: Merge AuxPoW support from Namecore Changes are as below: Wrap CBlockHeader::nVersion into a new class (CBlockVersion). This allows to take care of interpreting the field into a base version, auxpow flag and the chain ID. Update getauxblock.py for new 'generate' RPC call. Add 'auxpow' to block JSON. Accept auxpow as PoW verification. Add unit tests for auxpow verification. Add check for memory-layout of CBlockVersion. Weaken auxpow chain ID checks for the testnet. Allow Params() to overrule when to check the auxpow chain ID and for legacy blocks. Use this to disable the checks on testnet. Introduce CPureBlockHeader. Split the block header part that is used by auxpow and the "real" block header (that uses auxpow) to resolve the cyclic dependency between the two. Differentiate between uint256 and arith_uint256. This change was done upstream, modify the auxpow code. Add missing lock in auxpow_tests. Fix REST header check for auxpow headers. Those can be longer, thus take that into account. Also perform the check actually on an auxpow header. Correctly set the coinbase for getauxblock results. Call IncrementExtraNonce in getauxblock so that the coinbase is actually initialised with the stuff it should be. (BIP30 block height and COINBASE_FLAGS.) Implement getauxblock plus regression test. Turn auxpow test into FIXTURE test. This allows using of the Params() calls. Move CMerkleTx code to auxpow.cpp. Otherwise we get linker errors when building without wallet. Fix rebase with BIP66. Update the code to handle BIP66's nVersion=3. Enforce that auxpow parent blocks have no auxpow block version. This is for compatibility with namecoind. See also https://github.com/namecoin/namecoin/pull/199. Move auxpow-related parameters to Consensus::Params. --- src/rest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index 54eefcafe..e9d0a8cef 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -160,8 +160,9 @@ static bool rest_headers(HTTPRequest* req, } CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); + const CChainParams& chainparams = Params(); BOOST_FOREACH(const CBlockIndex *pindex, headers) { - ssHeader << pindex->GetBlockHeader(); + ssHeader << pindex->GetBlockHeader(chainparams.GetConsensus()); } switch (rf) { -- cgit v1.2.3 From 1be681a1b97b686f838af90682a57f2030d26015 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Thu, 28 Dec 2017 15:04:08 +0000 Subject: Modify chain consensus parameters to be height aware (#1396) * Modify chain consensus parameters to be height aware * Correct implementation of simplified rewards in parameters * Correct max money * Use base block version in IsSuperMajority() instead of full version * Correct mining of blocks in AuxPoW tests * Add in missing pre-AuxPoW consensus checks --- src/rest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/rest.cpp') diff --git a/src/rest.cpp b/src/rest.cpp index e9d0a8cef..7dc3a42f0 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -162,7 +162,7 @@ static bool rest_headers(HTTPRequest* req, CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); const CChainParams& chainparams = Params(); BOOST_FOREACH(const CBlockIndex *pindex, headers) { - ssHeader << pindex->GetBlockHeader(chainparams.GetConsensus()); + ssHeader << pindex->GetBlockHeader(chainparams.GetConsensus(pindex->nHeight)); } switch (rf) { @@ -222,7 +222,7 @@ static bool rest_block(HTTPRequest* req, if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus(pblockindex->nHeight))) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } @@ -363,7 +363,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) CTransactionRef tx; uint256 hashBlock = uint256(); - if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(0), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); -- cgit v1.2.3