diff --git a/Makefile.am b/Makefile.am index 647cf118..d5a443a2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,6 +53,8 @@ src_libbitcoin_node_la_SOURCES = \ src/chasers/chaser_template.cpp \ src/chasers/chaser_transaction.cpp \ src/chasers/chaser_validate.cpp \ + src/parse/query.cpp \ + src/parse/target.cpp \ src/protocols/protocol.cpp \ src/protocols/protocol_block_in_106.cpp \ src/protocols/protocol_block_in_31800.cpp \ @@ -70,8 +72,6 @@ src_libbitcoin_node_la_SOURCES = \ src/protocols/protocol_performer.cpp \ src/protocols/protocol_transaction_in_106.cpp \ src/protocols/protocol_transaction_out_106.cpp \ - src/rest/media.cpp \ - src/rest/parse.cpp \ src/sessions/session.cpp \ src/sessions/session_inbound.cpp \ src/sessions/session_manual.cpp \ @@ -107,9 +107,9 @@ test_libbitcoin_node_test_SOURCES = \ test/chasers/chaser_template.cpp \ test/chasers/chaser_transaction.cpp \ test/chasers/chaser_validate.cpp \ + test/parse/query.cpp \ + test/parse/target.cpp \ test/protocols/protocol.cpp \ - test/rest/media.cpp \ - test/rest/parse.cpp \ test/sessions/session.cpp endif WITH_TESTS @@ -200,6 +200,12 @@ include_bitcoin_node_impl_chasersdir = ${includedir}/bitcoin/node/impl/chasers include_bitcoin_node_impl_chasers_HEADERS = \ include/bitcoin/node/impl/chasers/chaser_organize.ipp +include_bitcoin_node_parsedir = ${includedir}/bitcoin/node/parse +include_bitcoin_node_parse_HEADERS = \ + include/bitcoin/node/parse/parse.hpp \ + include/bitcoin/node/parse/query.hpp \ + include/bitcoin/node/parse/target.hpp + include_bitcoin_node_protocolsdir = ${includedir}/bitcoin/node/protocols include_bitcoin_node_protocols_HEADERS = \ include/bitcoin/node/protocols/protocol.hpp \ @@ -229,11 +235,6 @@ include_bitcoin_node_protocols_HEADERS = \ include/bitcoin/node/protocols/protocol_ws.hpp \ include/bitcoin/node/protocols/protocols.hpp -include_bitcoin_node_restdir = ${includedir}/bitcoin/node/rest -include_bitcoin_node_rest_HEADERS = \ - include/bitcoin/node/rest/media.hpp \ - include/bitcoin/node/rest/parse.hpp - include_bitcoin_node_sessionsdir = ${includedir}/bitcoin/node/sessions include_bitcoin_node_sessions_HEADERS = \ include/bitcoin/node/sessions/session.hpp \ diff --git a/builds/cmake/CMakeLists.txt b/builds/cmake/CMakeLists.txt index c19df0f2..994371ce 100644 --- a/builds/cmake/CMakeLists.txt +++ b/builds/cmake/CMakeLists.txt @@ -265,6 +265,8 @@ add_library( ${CANONICAL_LIB_NAME} "../../src/chasers/chaser_template.cpp" "../../src/chasers/chaser_transaction.cpp" "../../src/chasers/chaser_validate.cpp" + "../../src/parse/query.cpp" + "../../src/parse/target.cpp" "../../src/protocols/protocol.cpp" "../../src/protocols/protocol_block_in_106.cpp" "../../src/protocols/protocol_block_in_31800.cpp" @@ -282,8 +284,6 @@ add_library( ${CANONICAL_LIB_NAME} "../../src/protocols/protocol_performer.cpp" "../../src/protocols/protocol_transaction_in_106.cpp" "../../src/protocols/protocol_transaction_out_106.cpp" - "../../src/rest/media.cpp" - "../../src/rest/parse.cpp" "../../src/sessions/session.cpp" "../../src/sessions/session_inbound.cpp" "../../src/sessions/session_manual.cpp" @@ -349,9 +349,9 @@ if (with-tests) "../../test/chasers/chaser_template.cpp" "../../test/chasers/chaser_transaction.cpp" "../../test/chasers/chaser_validate.cpp" + "../../test/parse/query.cpp" + "../../test/parse/target.cpp" "../../test/protocols/protocol.cpp" - "../../test/rest/media.cpp" - "../../test/rest/parse.cpp" "../../test/sessions/session.cpp" ) add_test( NAME libbitcoin-node-test COMMAND libbitcoin-node-test diff --git a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj index de7aa517..f35618ab 100644 --- a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj @@ -134,9 +134,9 @@ + + - - diff --git a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters index 701c4694..7caa76ff 100644 --- a/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-node-test/libbitcoin-node-test.vcxproj.filters @@ -13,10 +13,10 @@ {4BD50864-D3BC-4F64-0000-000000000001} - + {4BD50864-D3BC-4F64-0000-000000000002} - + {4BD50864-D3BC-4F64-0000-000000000003} @@ -72,14 +72,14 @@ src - - src\protocols + + src\parse - - src\rest + + src\parse - - src\rest + + src\protocols src\sessions diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj index adb38705..893eff0d 100644 --- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj @@ -137,6 +137,8 @@ + + @@ -155,8 +157,6 @@ - - @@ -192,6 +192,9 @@ + + + @@ -219,8 +222,6 @@ - - diff --git a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters index 11beb04e..94a9284d 100644 --- a/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-node/libbitcoin-node.vcxproj.filters @@ -28,10 +28,10 @@ {5FFB5F52-0772-4404-0000-00000000000F} - + {5FFB5F52-0772-4404-0000-00000000000C} - + {5FFB5F52-0772-4404-0000-00000000000D} @@ -49,10 +49,10 @@ {5FFB5F52-0772-4404-0000-000000000002} - + {5FFB5F52-0772-4404-0000-000000000003} - + {5FFB5F52-0772-4404-0000-000000000004} @@ -108,6 +108,12 @@ src + + src\parse + + + src\parse + src @@ -162,12 +168,6 @@ src\protocols - - src\rest - - - src\rest - src\sessions @@ -269,6 +269,15 @@ include\bitcoin\node + + include\bitcoin\node\parse + + + include\bitcoin\node\parse + + + include\bitcoin\node\parse + include\bitcoin\node @@ -350,12 +359,6 @@ include\bitcoin\node\protocols - - include\bitcoin\node\rest - - - include\bitcoin\node\rest - include\bitcoin\node\sessions diff --git a/include/bitcoin/node.hpp b/include/bitcoin/node.hpp index 3d166ce1..735648e6 100644 --- a/include/bitcoin/node.hpp +++ b/include/bitcoin/node.hpp @@ -45,6 +45,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -71,8 +74,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/include/bitcoin/node/error.hpp b/include/bitcoin/node/error.hpp index abea94ce..d0ce214c 100644 --- a/include/bitcoin/node/error.hpp +++ b/include/bitcoin/node/error.hpp @@ -115,7 +115,8 @@ enum error_t : uint8_t missing_component, invalid_component, invalid_subcomponent, - extra_segment + extra_segment, + unexpected_parse }; // No current need for error_code equivalence mapping. diff --git a/include/bitcoin/node/parse/parse.hpp b/include/bitcoin/node/parse/parse.hpp new file mode 100644 index 00000000..170ccdf8 --- /dev/null +++ b/include/bitcoin/node/parse/parse.hpp @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_NODE_PARSE_PARSE_HPP +#define LIBBITCOIN_NODE_PARSE_PARSE_HPP + +#include +#include + +#endif diff --git a/include/bitcoin/node/rest/media.hpp b/include/bitcoin/node/parse/query.hpp similarity index 87% rename from include/bitcoin/node/rest/media.hpp rename to include/bitcoin/node/parse/query.hpp index 9eafec7b..b4706ecb 100644 --- a/include/bitcoin/node/rest/media.hpp +++ b/include/bitcoin/node/parse/query.hpp @@ -16,15 +16,15 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#ifndef LIBBITCOIN_NODE_MEDIA_HPP -#define LIBBITCOIN_NODE_MEDIA_HPP +#ifndef LIBBITCOIN_NODE_PARSE_QUERY_HPP +#define LIBBITCOIN_NODE_PARSE_QUERY_HPP #include namespace libbitcoin { namespace node { -BCN_API bool get_acceptable_media_type(network::http::media_type& out, +BCN_API bool parse_query(network::rpc::request_t& out, const network::http::request& request) NOEXCEPT; } // namespace network diff --git a/include/bitcoin/node/rest/parse.hpp b/include/bitcoin/node/parse/target.hpp similarity index 87% rename from include/bitcoin/node/rest/parse.hpp rename to include/bitcoin/node/parse/target.hpp index b46a1b8a..d64f33ca 100644 --- a/include/bitcoin/node/rest/parse.hpp +++ b/include/bitcoin/node/parse/target.hpp @@ -16,15 +16,15 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#ifndef LIBBITCOIN_NODE_PARSE_HPP -#define LIBBITCOIN_NODE_PARSE_HPP +#ifndef LIBBITCOIN_NODE_PARSE_TARGET_HPP +#define LIBBITCOIN_NODE_PARSE_TARGET_HPP #include namespace libbitcoin { namespace node { -BCN_API code parse_request(network::rpc::request_t& out, +BCN_API code parse_target(network::rpc::request_t& out, const std::string_view& path) NOEXCEPT; } // namespace network diff --git a/include/bitcoin/node/protocols/protocol_explore.hpp b/include/bitcoin/node/protocols/protocol_explore.hpp index ceefabc0..902905a9 100644 --- a/include/bitcoin/node/protocols/protocol_explore.hpp +++ b/include/bitcoin/node/protocols/protocol_explore.hpp @@ -20,6 +20,7 @@ #define LIBBITCOIN_NODE_PROTOCOLS_PROTOCOL_EXPLORE_HPP #include +#include #include #include @@ -32,6 +33,8 @@ class BCN_API protocol_explore { public: typedef std::shared_ptr ptr; + using interface = network::rpc::interface::explore; + using dispatcher = network::rpc::dispatcher; protocol_explore(const auto& session, const network::channel::ptr& channel, @@ -41,16 +44,68 @@ class BCN_API protocol_explore { } - /// Public start is required. - void start() NOEXCEPT override + void start() NOEXCEPT override; + void stopping(const code& ec) NOEXCEPT override; + +protected: + template + inline void subscribe(Method&& method, Args&&... args) NOEXCEPT { - node::protocol_html::start(); + dispatcher_.subscribe(BIND_SHARED(method, args)); } -protected: /// Dispatch. bool try_dispatch_object( const network::http::request& request) NOEXCEPT override; + + /// REST interface handlers. + + bool handle_get_block(const code& ec, interface::block, + uint8_t version, uint8_t media, std::optional hash, + std::optional height, bool witness) NOEXCEPT; + bool handle_get_header(const code& ec, interface::header, + uint8_t version, uint8_t media, std::optional hash, + std::optional height) NOEXCEPT; + ////bool handle_get_filter(const code& ec, interface::filter, + //// uint8_t version, uint8_t media, std::optional hash, + //// std::optional height) NOEXCEPT; + ////bool handle_get_block_txs(const code& ec, interface::block_txs, + //// uint8_t version, uint8_t media, std::optional hash, + //// std::optional height) NOEXCEPT; + //// + ////bool handle_get_block_tx(const code& ec, interface::block_tx, + //// uint8_t version, uint8_t media, uint32_t position, + //// std::optional hash, + //// std::optional height, bool witness) NOEXCEPT; + //// + bool handle_get_transaction(const code& ec, interface::transaction, + uint8_t version, uint8_t media, system::hash_cptr hash, + bool witness) NOEXCEPT; + ////bool handle_get_address(const code& ec, interface::address, + //// uint8_t version, uint8_t media, system::hash_cptr hash) NOEXCEPT; + //// + ////bool handle_get_input(const code& ec, interface::input, + //// uint8_t version, uint8_t media, system::hash_cptr hash, + //// std::optional index) NOEXCEPT; + ////bool handle_get_input_script(const code& ec, interface::input_script, + //// uint8_t version, uint8_t media, system::hash_cptr hash, + //// std::optional index) NOEXCEPT; + ////bool handle_get_input_witness(const code& ec, interface::input_witness, + //// uint8_t version, uint8_t media, system::hash_cptr hash, + //// std::optional index) NOEXCEPT; + //// + ////bool handle_get_output(const code& ec, interface::output, + //// uint8_t version, uint8_t media, system::hash_cptr hash, + //// std::optional index) NOEXCEPT; + ////bool handle_get_output_script(const code& ec, interface::output_script, + //// uint8_t version, uint8_t media, system::hash_cptr hash, + //// std::optional index) NOEXCEPT; + ////bool handle_get_output_spender(const code& ec, interface::output_spender, + //// uint8_t version, uint8_t media, system::hash_cptr hash, + //// std::optional index) NOEXCEPT; + +private: + dispatcher dispatcher_{}; }; } // namespace node diff --git a/src/error.cpp b/src/error.cpp index d1fd7f45..5765cd80 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -105,7 +105,8 @@ DEFINE_ERROR_T_MESSAGE_MAP(error) { missing_component, "missing_component" }, { invalid_component, "invalid_component" }, { invalid_subcomponent, "invalid_subcomponent" }, - { extra_segment, "extra_segment" } + { extra_segment, "extra_segment" }, + { unexpected_parse, "unexpected_parse" } }; DEFINE_ERROR_T_CATEGORY(error, "node", "node code") diff --git a/src/rest/media.cpp b/src/parse/query.cpp similarity index 64% rename from src/rest/media.cpp rename to src/parse/query.cpp index 48a51778..2e536897 100644 --- a/src/rest/media.cpp +++ b/src/parse/query.cpp @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#include +#include #include @@ -24,10 +24,10 @@ namespace libbitcoin { namespace node { using namespace system; +using namespace network; using namespace network::http; -bool get_acceptable_media_type(media_type& out, - const request& request) NOEXCEPT +bool parse_query(rpc::request_t& out, const request& request) NOEXCEPT { wallet::uri uri{}; if (!uri.decode(request.target())) @@ -36,24 +36,42 @@ bool get_acceptable_media_type(media_type& out, constexpr auto text = media_type::text_plain; constexpr auto json = media_type::application_json; constexpr auto data = media_type::application_octet_stream; + + auto query = uri.decode_query(); + const auto format = query["format"]; + + if (!out.params.has_value() || + !std::holds_alternative(out.params.value())) + return false; + + auto& params = std::get(out.params.value()); + const auto& witness = query["witness"]; + + // Validate prper bool value if set. + if (!witness.empty() && witness != "true" && witness != "false") + return false; + + // Witness is optional (where applicable) so only set if false. + if (witness == "false") + params["witness"] = false; + const auto accepts = to_media_types((request)[field::accept]); - const auto format = uri.decode_query()["format"]; if (contains(accepts, json) || format == "json") { - out = json; + params["media"] = to_value(json); return true; } if (contains(accepts, text) || format == "text") { - out = text; + params["media"] = to_value(text); return true; } if (contains(accepts, data) || format == "data") { - out = data; + params["media"] = to_value(data); return true; } diff --git a/src/rest/parse.cpp b/src/parse/target.cpp similarity index 92% rename from src/rest/parse.cpp rename to src/parse/target.cpp index 985ee657..03d7709f 100644 --- a/src/rest/parse.cpp +++ b/src/parse/target.cpp @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#include +#include #include #include @@ -35,8 +35,8 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) template static bool to_number(Number& out, const std::string_view& token) NOEXCEPT { - return !token.empty() && is_ascii_numeric(token) && token.front() != '0' && - deserialize(out, token); + return !token.empty() && is_ascii_numeric(token) && (is_one(token.size()) || + token.front() != '0') && deserialize(out, token); } static hash_cptr to_hash(const std::string_view& token) NOEXCEPT @@ -46,9 +46,10 @@ static hash_cptr to_hash(const std::string_view& token) NOEXCEPT emplace_shared(std::move(out)) : hash_cptr{}; } -code parse_request(request_t& out, const std::string_view& path) NOEXCEPT +code parse_target(request_t& out, const std::string_view& path) NOEXCEPT { - if (path.empty()) + const auto clean = split(path, "?", false, false).front(); + if (clean.empty()) return error::empty_path; // Avoid conflict with node type. @@ -65,7 +66,7 @@ code parse_request(request_t& out, const std::string_view& path) NOEXCEPT auto& method = out.method; auto& params = std::get(out.params.value()); - const auto segments = split(path, "/", false, true); + const auto segments = split(clean, "/", false, true); BC_ASSERT(!segments.empty()); size_t segment{}; @@ -113,7 +114,7 @@ code parse_request(request_t& out, const std::string_view& path) NOEXCEPT const auto hash = to_hash(segments[segment++]); if (!hash) return error::invalid_hash; - method = "inputs"; + method = "input"; params["hash"] = hash; } else if (target == "outputs") @@ -124,7 +125,7 @@ code parse_request(request_t& out, const std::string_view& path) NOEXCEPT const auto hash = to_hash(segments[segment++]); if (!hash) return error::invalid_hash; - method = "outputs"; + method = "output"; params["hash"] = hash; } else if (target == "input") @@ -142,11 +143,11 @@ code parse_request(request_t& out, const std::string_view& path) NOEXCEPT const auto component = segments[segment++]; if (component == "scripts") { - method = "input_scripts"; + method = "input_script"; } else if (component == "witnesses") { - method = "input_witnesses"; + method = "input_witness"; } else { @@ -186,11 +187,11 @@ code parse_request(request_t& out, const std::string_view& path) NOEXCEPT const auto component = segments[segment++]; if (component == "scripts") { - method = "output_scripts"; + method = "output_script"; } else if (component == "spenders") { - method = "output_spenders"; + method = "output_spender"; } else { diff --git a/src/protocols/protocol_explore.cpp b/src/protocols/protocol_explore.cpp index ae589361..6041f939 100644 --- a/src/protocols/protocol_explore.cpp +++ b/src/protocols/protocol_explore.cpp @@ -18,139 +18,197 @@ */ #include +#include #include -#include -#include +#include namespace libbitcoin { namespace node { #define CLASS protocol_explore + +#define SUBSCRIBE_EXPLORE(method, ...) \ + subscribe(&CLASS::method, __VA_ARGS__) using namespace system; using namespace network::rpc; using namespace network::http; +using namespace std::placeholders; + +// Avoiding namespace conflict. +using object_type = network::rpc::object_t; BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) +// Start. +// ---------------------------------------------------------------------------- + +void protocol_explore::start() NOEXCEPT +{ + BC_ASSERT(stranded()); + + if (started()) + return; + + SUBSCRIBE_EXPLORE(handle_get_block, _1, _2, _3, _4, _5, _6, _7); + SUBSCRIBE_EXPLORE(handle_get_header, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_filter, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_block_txs, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_block_tx, _1, _2, _3, _4, _5, _6, _7, _8); + SUBSCRIBE_EXPLORE(handle_get_transaction, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_address, _1, _2, _3, _4, _5); + ////SUBSCRIBE_EXPLORE(handle_get_input, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_input_script, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_input_witness, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_output, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_output_script, _1, _2, _3, _4, _5, _6); + ////SUBSCRIBE_EXPLORE(handle_get_output_spender, _1, _2, _3, _4, _5, _6); + protocol_html::start(); +} + +void protocol_explore::stopping(const code& ec) NOEXCEPT +{ + BC_ASSERT(stranded()); + dispatcher_.stop(ec); + protocol_html::stopping(ec); +} + // Dispatch. // ---------------------------------------------------------------------------- bool protocol_explore::try_dispatch_object(const request& request) NOEXCEPT { - media_type accept{}; - if (!get_acceptable_media_type(accept, request)) + request_t model{}; + if (const auto ec = parse_target(model, request.target())) + return false; + + if (!parse_query(model, request)) { - send_bad_target(request); + send_not_acceptable(request); return true; } - request_t out{}; - if (const auto ec = parse_request(out, request.target())) + if (const auto ec = dispatcher_.notify(model)) + send_internal_server_error(request, ec); + + return true; +} + +// Handlers. +// ---------------------------------------------------------------------------- + +bool protocol_explore::handle_get_block(const code& ec, interface::block, + uint8_t, uint8_t media, std::optional hash, + std::optional height, bool witness) NOEXCEPT +{ + BC_ASSERT(stranded()); + + if (stopped(ec)) + return false; + + const auto& query = archive(); + const auto link = hash.has_value() ? query.to_header(*(hash.value())) : + query.to_confirmed(height.value()); + + // TODO: there's no request. + const network::http::request request{}; + + if (const auto ptr = query.get_block(link, witness)) { - send_bad_target(request, ec); - return true; + switch (media) + { + case to_value(media_type::application_octet_stream): + send_data(request, ptr->to_data(witness)); + return true; + case to_value(media_type::text_plain): + send_text(request, encode_base16(ptr->to_data(witness))); + return true; + case to_value(media_type::application_json): + send_json(request, value_from(ptr), + ptr->serialized_size(witness)); + return true; + } } - ////const auto& query = archive(); - ////const auto wit = params["witness"] != "false"; - ////constexpr auto header_size = chain::header::serialized_size(); - - ////if (accept == media_type::application_json) - ////{ - //// if (hd) - //// { - //// if (const auto ptr = query.get_header(query.to_header(hash))) - //// { - //// send_json(request, value_from(ptr), header_size); - //// return true; - //// } - //// } - //// else if (bk) - //// { - //// if (const auto ptr = query.get_block(query.to_header(hash), wit)) - //// { - //// send_json(request, value_from(ptr), ptr->serialized_size(wit)); - //// return true; - //// } - //// } - //// else - //// { - //// if (const auto ptr = query.get_transaction(query.to_tx(hash), wit)) - //// { - //// send_json(request, value_from(ptr), ptr->serialized_size(wit)); - //// return true; - //// } - //// } - - //// send_not_found(request); - //// return true; - ////} - - ////if (accept == media_type::text_plain) - ////{ - //// if (hd) - //// { - //// if (const auto ptr = query.get_header(query.to_header(hash))) - //// { - //// send_text(request, encode_base16(ptr->to_data())); - //// return true; - //// } - //// } - //// else if (bk) - //// { - //// if (const auto ptr = query.get_block(query.to_header(hash), wit)) - //// { - //// send_text(request, encode_base16(ptr->to_data(wit))); - //// return true; - //// } - //// } - //// else - //// { - //// if (const auto ptr = query.get_transaction(query.to_tx(hash), wit)) - //// { - //// send_text(request, encode_base16(ptr->to_data(wit))); - //// return true; - //// } - //// } - - //// send_not_found(request); - //// return true; - ////} - - ////////if (accept == media_type::application_octet_stream) - ////{ - //// if (hd) - //// { - //// if (const auto ptr = query.get_header(query.to_header(hash))) - //// { - //// send_data(request, ptr->to_data()); - //// return true; - //// } - //// } - //// else if (bk) - //// { - //// if (const auto ptr = query.get_block(query.to_header(hash), wit)) - //// { - //// send_data(request, ptr->to_data(wit)); - //// return true; - //// } - //// } - //// else - //// { - //// if (const auto ptr = query.get_transaction(query.to_tx(hash), wit)) - //// { - //// send_data(request, ptr->to_data(wit)); - //// return true; - //// } - //// } - - //// send_not_found(request); - //// return true; - ////} + send_not_found(request); + return true; +} + +bool protocol_explore::handle_get_header(const code& ec, interface::header, + uint8_t, uint8_t media, std::optional hash, + std::optional height) NOEXCEPT +{ + BC_ASSERT(stranded()); + + if (stopped(ec)) + return false; + + const auto& query = archive(); + const auto link = hash.has_value() ? query.to_header(*(hash.value())) : + query.to_confirmed(height.value()); + + // TODO: there's no request. + const network::http::request request{}; + + if (const auto ptr = query.get_header(link)) + { + switch (media) + { + case to_value(media_type::application_octet_stream): + send_data(request, ptr->to_data()); + return true; + case to_value(media_type::text_plain): + send_text(request, encode_base16(ptr->to_data())); + return true; + case to_value(media_type::application_json): + send_json(request, value_from(ptr), + chain::header::serialized_size()); + return true; + } + } + + send_not_found(request); + return true; +} + +bool protocol_explore::handle_get_transaction(const code& ec, + interface::transaction, uint8_t, uint8_t media, system::hash_cptr hash, + bool witness) NOEXCEPT +{ + BC_ASSERT(stranded()); + + if (stopped(ec)) + return false; + + const auto& query = archive(); + + // TODO: there's no request. + const network::http::request request{}; + + if (const auto ptr = query.get_transaction(query.to_tx(*hash), witness)) + { + switch (media) + { + case to_value(media_type::application_octet_stream): + send_data(request, ptr->to_data(witness)); + return true; + case to_value(media_type::text_plain): + send_text(request, encode_base16(ptr->to_data(witness))); + return true; + case to_value(media_type::application_json): + send_json(request, value_from(ptr), + ptr->serialized_size(witness)); + return true; + } + } + + send_not_found(request); + return true; } BC_POP_WARNING() +#undef SUBSCRIBE_EXPLORE + } // namespace node } // namespace libbitcoin diff --git a/test/error.cpp b/test/error.cpp index 1fe24d46..cd5f9b55 100644 --- a/test/error.cpp +++ b/test/error.cpp @@ -362,4 +362,13 @@ BOOST_AUTO_TEST_CASE(error_t__code__extra_segment__true_exected_message) BOOST_REQUIRE_EQUAL(ec.message(), "extra_segment"); } +BOOST_AUTO_TEST_CASE(error_t__code__unexpected_parse__true_exected_message) +{ + constexpr auto value = error::unexpected_parse; + const auto ec = code(value); + BOOST_REQUIRE(ec); + BOOST_REQUIRE(ec == value); + BOOST_REQUIRE_EQUAL(ec.message(), "unexpected_parse"); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/test/rest/media.cpp b/test/parse/query.cpp similarity index 85% rename from test/rest/media.cpp rename to test/parse/query.cpp index d8d04d3d..f90f55a2 100644 --- a/test/rest/media.cpp +++ b/test/parse/query.cpp @@ -22,10 +22,10 @@ BOOST_AUTO_TEST_SUITE(media_tests) using namespace network::http; -BOOST_AUTO_TEST_CASE(media__get_acceptable_media_type__empty__false) +BOOST_AUTO_TEST_CASE(media__parse_query__empty__false) { - media_type out{}; - BOOST_REQUIRE(!get_acceptable_media_type(out, request{})); + network::rpc::request_t out{}; + BOOST_REQUIRE(!parse_query(out, network::http::request{})); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/rest/parse.cpp b/test/parse/target.cpp similarity index 68% rename from test/rest/parse.cpp rename to test/parse/target.cpp index e6411726..867c1c11 100644 --- a/test/rest/parse.cpp +++ b/test/parse/target.cpp @@ -26,51 +26,51 @@ using object_t = network::rpc::object_t; // General errors -BOOST_AUTO_TEST_CASE(parse__parse_request__empty_path__empty_path) +BOOST_AUTO_TEST_CASE(parse__parse_target__empty_path__empty_path) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, ""), node::error::empty_path); + BOOST_REQUIRE_EQUAL(parse_target(out, "?foo=bar"), node::error::empty_path); } -BOOST_AUTO_TEST_CASE(parse__parse_request__missing_version__missing_version) +BOOST_AUTO_TEST_CASE(parse__parse_target__missing_version__missing_version) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/"), node::error::missing_version); - BOOST_REQUIRE_EQUAL(parse_request(out, "/block/height/123"), node::error::missing_version); + BOOST_REQUIRE_EQUAL(parse_target(out, "/"), node::error::missing_version); + BOOST_REQUIRE_EQUAL(parse_target(out, "/block/height/123"), node::error::missing_version); } -BOOST_AUTO_TEST_CASE(parse__parse_request__invalid_version__invalid_number) +BOOST_AUTO_TEST_CASE(parse__parse_target__invalid_version__invalid_number) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/vinvalid/block/height/123"), node::error::invalid_number); + BOOST_REQUIRE_EQUAL(parse_target(out, "/vinvalid/block/height/123"), node::error::invalid_number); } -BOOST_AUTO_TEST_CASE(parse__parse_request__version_leading_zero__invalid_number) +BOOST_AUTO_TEST_CASE(parse__parse_target__version_leading_zero__invalid_number) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v01/block/height/123"), node::error::invalid_number); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v01/block/height/123"), node::error::invalid_number); } -BOOST_AUTO_TEST_CASE(parse__parse_request__missing_target__missing_target) +BOOST_AUTO_TEST_CASE(parse__parse_target__missing_target__missing_target) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3"), node::error::missing_target); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3"), node::error::missing_target); } -BOOST_AUTO_TEST_CASE(parse__parse_request__invalid_target__invalid_target) +BOOST_AUTO_TEST_CASE(parse__parse_target__invalid_target__invalid_target) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/invalid"), node::error::invalid_target); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/invalid"), node::error::invalid_target); } // block/hash -BOOST_AUTO_TEST_CASE(parse__parse_request__block_hash_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_hash_valid__expected) { - const std::string path = "//v42//block//hash//0000000000000000000000000000000000000000000000000000000000000042//"; + const std::string path = "//v42//block//hash//0000000000000000000000000000000000000000000000000000000000000042//?foo=bar"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "block"); BOOST_REQUIRE(request.params.has_value()); @@ -91,37 +91,37 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__block_hash_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_hash_missing_hash__missing_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_hash_missing_hash__missing_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/hash"), node::error::missing_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/hash"), node::error::missing_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_hash_invalid_hash__invalid_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_hash_invalid_hash__invalid_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/hash/invalidhex"), node::error::invalid_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/hash/invalidhex"), node::error::invalid_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_hash_invalid_component__invalid_component) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_hash_invalid_component__invalid_component) { const std::string path = "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/invalid"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::invalid_component); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::invalid_component); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_invalid_id_type__invalid_id_type) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_invalid_id_type__invalid_id_type) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/invalid/123"), node::error::invalid_id_type); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/invalid/123"), node::error::invalid_id_type); } // header/height -BOOST_AUTO_TEST_CASE(parse__parse_request__header_height_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__header_height_valid__expected) { request_t request{}; - BOOST_REQUIRE(!parse_request(request, "/v42/block/height/123456/header/")); + BOOST_REQUIRE(!parse_target(request, "/v42/block/height/123456/header/")); BOOST_REQUIRE_EQUAL(request.method, "header"); BOOST_REQUIRE(request.params.has_value()); @@ -138,20 +138,20 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__header_height_valid__expected) BOOST_REQUIRE_EQUAL(height, 123456u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__header_height_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__header_height_extra_segment__extra_segment) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/height/123/header/extra"), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/height/123/header/extra"), node::error::extra_segment); } // header/hash -BOOST_AUTO_TEST_CASE(parse__parse_request__header_hash_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__header_hash_valid__expected) { const std::string path = "v42/block/hash/0000000000000000000000000000000000000000000000000000000000000042/header"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "header"); BOOST_REQUIRE(request.params.has_value()); @@ -172,19 +172,19 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__header_hash_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__header_hash_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__header_hash_extra_segment__extra_segment) { const std::string path = "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/header/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // filter/height -BOOST_AUTO_TEST_CASE(parse__parse_request__filter_height_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__filter_height_valid__expected) { request_t request{}; - BOOST_REQUIRE(!parse_request(request, "v42/block/height/123456/filter/")); + BOOST_REQUIRE(!parse_target(request, "v42/block/height/123456/filter/")); BOOST_REQUIRE_EQUAL(request.method, "filter"); BOOST_REQUIRE(request.params.has_value()); @@ -201,20 +201,20 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__filter_height_valid__expected) BOOST_REQUIRE_EQUAL(height, 123456u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__filter_height_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__filter_height_extra_segment__extra_segment) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/height/123/filter/extra"), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/height/123/filter/extra"), node::error::extra_segment); } // filter/hash -BOOST_AUTO_TEST_CASE(parse__parse_request__filter_hash_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__filter_hash_valid__expected) { const std::string path = "/v42/block/hash/0000000000000000000000000000000000000000000000000000000000000042/filter"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "filter"); BOOST_REQUIRE(request.params.has_value()); @@ -235,19 +235,19 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__filter_hash_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__filter_hash_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__filter_hash_extra_segment__extra_segment) { const std::string path = "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/filter/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // block_txs/height -BOOST_AUTO_TEST_CASE(parse__parse_request__block_txs_height_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_txs_height_valid__expected) { request_t request{}; - BOOST_REQUIRE(!parse_request(request, "/v42/block/height/123456/transactions")); + BOOST_REQUIRE(!parse_target(request, "/v42/block/height/123456/transactions")); BOOST_REQUIRE_EQUAL(request.method, "block_txs"); BOOST_REQUIRE(request.params.has_value()); @@ -264,20 +264,20 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__block_txs_height_valid__expected) BOOST_REQUIRE_EQUAL(height, 123456u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_txs_height_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_txs_height_extra_segment__extra_segment) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/height/123/transactions/extra"), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/height/123/transactions/extra"), node::error::extra_segment); } // block_txs/hash -BOOST_AUTO_TEST_CASE(parse__parse_request__block_txs_hash_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_txs_hash_valid__expected) { const std::string path = "/v42/block/hash/0000000000000000000000000000000000000000000000000000000000000042/transactions"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "block_txs"); BOOST_REQUIRE(request.params.has_value()); @@ -298,19 +298,19 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__block_txs_hash_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_txs_hash_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_txs_hash_extra_segment__extra_segment) { const std::string path = "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/transactions/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // block_tx/height -BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_height_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_tx_height_valid__expected) { request_t request{}; - BOOST_REQUIRE(!parse_request(request, "/v42/block/height/123456/transaction/7")); + BOOST_REQUIRE(!parse_target(request, "/v42/block/height/123456/transaction/7")); BOOST_REQUIRE_EQUAL(request.method, "block_tx"); BOOST_REQUIRE(request.params.has_value()); @@ -330,32 +330,32 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_height_valid__expected) BOOST_REQUIRE_EQUAL(position, 7u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_height_missing_position__missing_position) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_tx_height_missing_position__missing_position) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/height/123/transaction"), node::error::missing_position); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/height/123/transaction"), node::error::missing_position); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_height_invalid_position__invalid_number) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_tx_height_invalid_position__invalid_number) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/height/123/transaction/invalid"), node::error::invalid_number); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/height/123/transaction/invalid"), node::error::invalid_number); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_height_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_tx_height_extra_segment__extra_segment) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/height/123/transaction/7/extra"), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/height/123/transaction/7/extra"), node::error::extra_segment); } // block_tx/hash -BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_hash_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_tx_hash_valid__expected) { const std::string path = "/v42/block/hash/0000000000000000000000000000000000000000000000000000000000000042/transaction/7"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "block_tx"); BOOST_REQUIRE(request.params.has_value()); @@ -379,34 +379,34 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_hash_valid__expected) BOOST_REQUIRE_EQUAL(position, 7u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_hash_missing_position__missing_position) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_tx_hash_missing_position__missing_position) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/transaction"), node::error::missing_position); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/transaction"), node::error::missing_position); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_hash_invalid_position__invalid_number) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_tx_hash_invalid_position__invalid_number) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/transaction/invalid"), node::error::invalid_number); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/transaction/invalid"), node::error::invalid_number); } -BOOST_AUTO_TEST_CASE(parse__parse_request__block_tx_hash_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__block_tx_hash_extra_segment__extra_segment) { const std::string path = "/v3/block/hash/0000000000000000000000000000000000000000000000000000000000000000/transaction/7/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // inputs -BOOST_AUTO_TEST_CASE(parse__parse_request__inputs_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__inputs_valid__expected) { const std::string path = "/v255/inputs/0000000000000000000000000000000000000000000000000000000000000042"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); - BOOST_REQUIRE_EQUAL(request.method, "inputs"); + BOOST_REQUIRE(!parse_target(request, path)); + BOOST_REQUIRE_EQUAL(request.method, "input"); BOOST_REQUIRE(request.params.has_value()); const auto& params = request.params.value(); @@ -426,33 +426,33 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__inputs_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__inputs_missing_hash__missing_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__inputs_missing_hash__missing_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/inputs"), node::error::missing_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/inputs"), node::error::missing_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__inputs_invalid_hash__invalid_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__inputs_invalid_hash__invalid_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/inputs/invalidhex"), node::error::invalid_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/inputs/invalidhex"), node::error::invalid_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__inputs_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__inputs_extra_segment__extra_segment) { const std::string path = "/v3/inputs/0000000000000000000000000000000000000000000000000000000000000000/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // input -BOOST_AUTO_TEST_CASE(parse__parse_request__input_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_valid__expected) { const std::string path = "/v255/input/0000000000000000000000000000000000000000000000000000000000000042/3"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "input"); BOOST_REQUIRE(request.params.has_value()); @@ -476,40 +476,40 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__input_valid__expected) BOOST_REQUIRE_EQUAL(index, 3u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_missing_hash__missing_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_missing_hash__missing_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/input"), node::error::missing_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/input"), node::error::missing_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_invalid_hash__invalid_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_invalid_hash__invalid_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/input/invalidhex/3"), node::error::invalid_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/input/invalidhex/3"), node::error::invalid_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_missing_component__missing_component) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_missing_component__missing_component) { const std::string path = "/v3/input/0000000000000000000000000000000000000000000000000000000000000000"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::missing_component); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::missing_component); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_invalid_index__invalid_number) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_invalid_index__invalid_number) { const std::string path = "/v3/input/0000000000000000000000000000000000000000000000000000000000000000/invalid"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::invalid_number); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::invalid_number); } // input_script -BOOST_AUTO_TEST_CASE(parse__parse_request__input_script_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_script_valid__expected) { const std::string path = "/v255/input/0000000000000000000000000000000000000000000000000000000000000042/3/script"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "input_script"); BOOST_REQUIRE(request.params.has_value()); @@ -533,29 +533,29 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__input_script_valid__expected) BOOST_REQUIRE_EQUAL(index, 3u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_script_invalid_subcomponent__invalid_subcomponent) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_script_invalid_subcomponent__invalid_subcomponent) { const std::string path = "/v3/input/0000000000000000000000000000000000000000000000000000000000000000/3/invalid"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::invalid_subcomponent); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::invalid_subcomponent); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_script_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_script_extra_segment__extra_segment) { const std::string path = "/v3/input/0000000000000000000000000000000000000000000000000000000000000000/3/script/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // input_scripts -BOOST_AUTO_TEST_CASE(parse__parse_request__input_scripts_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_scripts_valid__expected) { const std::string path = "/v255/input/0000000000000000000000000000000000000000000000000000000000000042/scripts"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); - BOOST_REQUIRE_EQUAL(request.method, "input_scripts"); + BOOST_REQUIRE(!parse_target(request, path)); + BOOST_REQUIRE_EQUAL(request.method, "input_script"); BOOST_REQUIRE(request.params.has_value()); const auto& params = request.params.value(); @@ -575,21 +575,21 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__input_scripts_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_scripts_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_scripts_extra_segment__extra_segment) { const std::string path = "/v3/input/0000000000000000000000000000000000000000000000000000000000000000/scripts/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // input_witness -BOOST_AUTO_TEST_CASE(parse__parse_request__input_witness_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_witness_valid__expected) { const std::string path = "/v255/input/0000000000000000000000000000000000000000000000000000000000000042/3/witness"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "input_witness"); BOOST_REQUIRE(request.params.has_value()); @@ -613,22 +613,22 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__input_witness_valid__expected) BOOST_REQUIRE_EQUAL(index, 3u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_witness_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_witness_extra_segment__extra_segment) { const std::string path = "/v3/input/0000000000000000000000000000000000000000000000000000000000000000/3/witness/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // input_witnesses -BOOST_AUTO_TEST_CASE(parse__parse_request__input_witnesses_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_witnesses_valid__expected) { const std::string path = "/v255/input/0000000000000000000000000000000000000000000000000000000000000042/witnesses"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); - BOOST_REQUIRE_EQUAL(request.method, "input_witnesses"); + BOOST_REQUIRE(!parse_target(request, path)); + BOOST_REQUIRE_EQUAL(request.method, "input_witness"); BOOST_REQUIRE(request.params.has_value()); const auto& params = request.params.value(); @@ -648,22 +648,22 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__input_witnesses_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__input_witnesses_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__input_witnesses_extra_segment__extra_segment) { const std::string path = "/v3/input/0000000000000000000000000000000000000000000000000000000000000000/witnesses/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // outputs -BOOST_AUTO_TEST_CASE(parse__parse_request__outputs_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__outputs_valid__expected) { const std::string path = "/v255/outputs/0000000000000000000000000000000000000000000000000000000000000042"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); - BOOST_REQUIRE_EQUAL(request.method, "outputs"); + BOOST_REQUIRE(!parse_target(request, path)); + BOOST_REQUIRE_EQUAL(request.method, "output"); BOOST_REQUIRE(request.params.has_value()); const auto& params = request.params.value(); @@ -683,33 +683,33 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__outputs_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__outputs_missing_hash__missing_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__outputs_missing_hash__missing_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/outputs"), node::error::missing_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/outputs"), node::error::missing_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__outputs_invalid_hash__invalid_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__outputs_invalid_hash__invalid_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/outputs/invalidhex"), node::error::invalid_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/outputs/invalidhex"), node::error::invalid_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__outputs_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__outputs_extra_segment__extra_segment) { const std::string path = "/v3/outputs/0000000000000000000000000000000000000000000000000000000000000000/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // output -BOOST_AUTO_TEST_CASE(parse__parse_request__output_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_valid__expected) { const std::string path = "/v255/output/0000000000000000000000000000000000000000000000000000000000000042/3"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "output"); BOOST_REQUIRE(request.params.has_value()); @@ -733,28 +733,28 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__output_valid__expected) BOOST_REQUIRE_EQUAL(index, 3u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__output_missing_component__missing_component) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_missing_component__missing_component) { const std::string path = "/v3/output/0000000000000000000000000000000000000000000000000000000000000000"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::missing_component); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::missing_component); } -BOOST_AUTO_TEST_CASE(parse__parse_request__output_invalid_index__invalid_number) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_invalid_index__invalid_number) { const std::string path = "/v3/output/0000000000000000000000000000000000000000000000000000000000000000/invalid"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::invalid_number); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::invalid_number); } // output_script -BOOST_AUTO_TEST_CASE(parse__parse_request__output_script_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_script_valid__expected) { const std::string path = "/v255/output/0000000000000000000000000000000000000000000000000000000000000042/3/script"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "output_script"); BOOST_REQUIRE(request.params.has_value()); @@ -778,29 +778,29 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__output_script_valid__expected) BOOST_REQUIRE_EQUAL(index, 3u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__output_script_invalid_subcomponent__invalid_subcomponent) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_script_invalid_subcomponent__invalid_subcomponent) { const std::string path = "/v3/output/0000000000000000000000000000000000000000000000000000000000000000/3/invalid"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::invalid_subcomponent); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::invalid_subcomponent); } -BOOST_AUTO_TEST_CASE(parse__parse_request__output_script_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_script_extra_segment__extra_segment) { const std::string path = "/v3/output/0000000000000000000000000000000000000000000000000000000000000000/3/script/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // output_scripts -BOOST_AUTO_TEST_CASE(parse__parse_request__output_scripts_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_scripts_valid__expected) { const std::string path = "/v255/output/0000000000000000000000000000000000000000000000000000000000000042/scripts"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); - BOOST_REQUIRE_EQUAL(request.method, "output_scripts"); + BOOST_REQUIRE(!parse_target(request, path)); + BOOST_REQUIRE_EQUAL(request.method, "output_script"); BOOST_REQUIRE(request.params.has_value()); const auto& params = request.params.value(); @@ -820,21 +820,21 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__output_scripts_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__output_scripts_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_scripts_extra_segment__extra_segment) { const std::string path = "/v3/output/0000000000000000000000000000000000000000000000000000000000000000/scripts/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // output_spender -BOOST_AUTO_TEST_CASE(parse__parse_request__output_spender_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_spender_valid__expected) { const std::string path = "/v255/output/0000000000000000000000000000000000000000000000000000000000000042/3/spender"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "output_spender"); BOOST_REQUIRE(request.params.has_value()); @@ -858,22 +858,22 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__output_spender_valid__expected) BOOST_REQUIRE_EQUAL(index, 3u); } -BOOST_AUTO_TEST_CASE(parse__parse_request__output_spender_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_spender_extra_segment__extra_segment) { const std::string path = "/v3/output/0000000000000000000000000000000000000000000000000000000000000000/3/spender/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // output_spenders -BOOST_AUTO_TEST_CASE(parse__parse_request__output_spenders_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_spenders_valid__expected) { const std::string path = "/v255/output/0000000000000000000000000000000000000000000000000000000000000042/spenders"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); - BOOST_REQUIRE_EQUAL(request.method, "output_spenders"); + BOOST_REQUIRE(!parse_target(request, path)); + BOOST_REQUIRE_EQUAL(request.method, "output_spender"); BOOST_REQUIRE(request.params.has_value()); const auto& params = request.params.value(); @@ -893,21 +893,21 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__output_spenders_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__output_spenders_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__output_spenders_extra_segment__extra_segment) { const std::string path = "/v3/output/0000000000000000000000000000000000000000000000000000000000000000/spenders/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } // address -BOOST_AUTO_TEST_CASE(parse__parse_request__address_valid__expected) +BOOST_AUTO_TEST_CASE(parse__parse_target__address_valid__expected) { const std::string path = "/v255/address/0000000000000000000000000000000000000000000000000000000000000042"; request_t request{}; - BOOST_REQUIRE(!parse_request(request, path)); + BOOST_REQUIRE(!parse_target(request, path)); BOOST_REQUIRE_EQUAL(request.method, "address"); BOOST_REQUIRE(request.params.has_value()); @@ -928,23 +928,23 @@ BOOST_AUTO_TEST_CASE(parse__parse_request__address_valid__expected) BOOST_REQUIRE_EQUAL(to_uintx(*hash_cptr), uint256_t{ 0x42 }); } -BOOST_AUTO_TEST_CASE(parse__parse_request__address_missing_hash__missing_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__address_missing_hash__missing_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/address"), node::error::missing_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/address"), node::error::missing_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__address_invalid_hash__invalid_hash) +BOOST_AUTO_TEST_CASE(parse__parse_target__address_invalid_hash__invalid_hash) { request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, "/v3/address/invalidhex"), node::error::invalid_hash); + BOOST_REQUIRE_EQUAL(parse_target(out, "/v3/address/invalidhex"), node::error::invalid_hash); } -BOOST_AUTO_TEST_CASE(parse__parse_request__address_extra_segment__extra_segment) +BOOST_AUTO_TEST_CASE(parse__parse_target__address_extra_segment__extra_segment) { const std::string path = "/v3/address/0000000000000000000000000000000000000000000000000000000000000000/extra"; request_t out{}; - BOOST_REQUIRE_EQUAL(parse_request(out, path), node::error::extra_segment); + BOOST_REQUIRE_EQUAL(parse_target(out, path), node::error::extra_segment); } BOOST_AUTO_TEST_SUITE_END()