Skip to content

Commit fd77dee

Browse files
authored
Merge pull request #592 from evoskuil/master
Add explore interface /configuration?format=json.
2 parents d5bd6bb + b75b021 commit fd77dee

5 files changed

Lines changed: 128 additions & 34 deletions

File tree

include/bitcoin/server/interfaces/explore.hpp

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ struct explore_methods
3030
{
3131
static constexpr std::tuple methods
3232
{
33+
method<"configuration", uint8_t, uint8_t>{ "version", "media" },
34+
3335
method<"top", uint8_t, uint8_t>{ "version", "media" },
3436
method<"block", uint8_t, uint8_t, nullable<system::hash_cptr>, nullable<uint32_t>, optional<true>>{ "version", "media", "hash", "height", "witness" },
3537
method<"block_header", uint8_t, uint8_t, nullable<system::hash_cptr>, nullable<uint32_t>>{ "version", "media", "hash", "height" },
@@ -70,37 +72,39 @@ struct explore_methods
7072

7173
// Derive this from above in c++26 using reflection.
7274

73-
using top = at<0>;
74-
75-
using block = at<1>;
76-
using block_header = at<2>;
77-
using block_header_context = at<3>;
78-
using block_details = at<4>;
79-
using block_txs = at<5>;
80-
using block_filter = at<6>;
81-
using block_filter_hash = at<7>;
82-
using block_filter_header = at<8>;
83-
using block_tx = at<9>;
84-
85-
using tx = at<10>;
86-
using tx_header = at<11>;
87-
using tx_details = at<12>;
88-
89-
using inputs = at<13>;
90-
using input = at<14>;
91-
using input_script = at<15>;
92-
using input_witness = at<16>;
93-
94-
using outputs = at<17>;
95-
using output = at<18>;
96-
using output_script = at<19>;
97-
using output_spender = at<20>;
98-
using output_spenders = at<21>;
99-
100-
using address = at<22>;
101-
using address_confirmed = at<23>;
102-
using address_unconfirmed = at<24>;
103-
using address_balance = at<25>;
75+
using configuration = at<0>;
76+
77+
using top = at<1>;
78+
79+
using block = at<2>;
80+
using block_header = at<3>;
81+
using block_header_context = at<4>;
82+
using block_details = at<5>;
83+
using block_txs = at<6>;
84+
using block_filter = at<7>;
85+
using block_filter_hash = at<8>;
86+
using block_filter_header = at<9>;
87+
using block_tx = at<10>;
88+
89+
using tx = at<11>;
90+
using tx_header = at<12>;
91+
using tx_details = at<13>;
92+
93+
using inputs = at<14>;
94+
using input = at<15>;
95+
using input_script = at<16>;
96+
using input_witness = at<17>;
97+
98+
using outputs = at<18>;
99+
using output = at<19>;
100+
using output_script = at<20>;
101+
using output_spender = at<21>;
102+
using output_spenders = at<22>;
103+
104+
using address = at<23>;
105+
using address_confirmed = at<24>;
106+
using address_unconfirmed = at<25>;
107+
using address_balance = at<26>;
104108
};
105109

106110
/// ?format=data|text|json (via query string).

include/bitcoin/server/protocols/protocol_explore.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class BCS_API protocol_explore
6363

6464
/// REST interface handlers.
6565

66+
bool handle_get_configuration(const code& ec, interface::configuration,
67+
uint8_t version, uint8_t media) NOEXCEPT;
68+
6669
bool handle_get_top(const code& ec, interface::top,
6770
uint8_t version, uint8_t media) NOEXCEPT;
6871

src/parsers/explore_target.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ code explore_target(request_t& out, const std::string_view& path) NOEXCEPT
8484
// transaction, address, inputs, and outputs are identical excluding names;
8585
// input and output are identical excluding names; block is unique.
8686
const auto target = segments[segment++];
87-
if (target == "top")
87+
if (target == "configuration")
88+
{
89+
method = "configuration";
90+
}
91+
else if (target == "top")
8892
{
8993
method = "top";
9094
}

src/protocols/protocol_explore.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ void protocol_explore::start() NOEXCEPT
7979
if (started())
8080
return;
8181

82-
SUBSCRIBE_EXPLORE(handle_get_top, _1, _2, _3, _4);
82+
SUBSCRIBE_EXPLORE(handle_get_configuration, _1, _2, _3, _4);
8383

84+
SUBSCRIBE_EXPLORE(handle_get_top, _1, _2, _3, _4);
8485
SUBSCRIBE_EXPLORE(handle_get_block, _1, _2, _3, _4, _5, _6, _7);
8586
SUBSCRIBE_EXPLORE(handle_get_block_header, _1, _2, _3, _4, _5, _6);
8687
SUBSCRIBE_EXPLORE(handle_get_block_header_context, _1, _2, _3, _4, _5, _6);
@@ -147,7 +148,7 @@ bool protocol_explore::try_dispatch_object(const http::request& request) NOEXCEP
147148
return true;
148149
}
149150

150-
// Handlers.
151+
// Serialization.
151152
// ----------------------------------------------------------------------------
152153

153154
constexpr auto data = to_value(http::media_type::application_octet_stream);
@@ -232,6 +233,32 @@ std::string to_hex_ptr_array(const Collection& collection, size_t size,
232233
return out;
233234
}
234235

236+
// Handlers.
237+
// ----------------------------------------------------------------------------
238+
239+
bool protocol_explore::handle_get_configuration(const code& ec,
240+
interface::configuration, uint8_t, uint8_t media) NOEXCEPT
241+
{
242+
if (stopped(ec))
243+
return false;
244+
245+
if (media != json)
246+
{
247+
send_not_acceptable();
248+
return true;
249+
}
250+
251+
const auto& query = archive();
252+
253+
value model{};
254+
auto& object = model.emplace_object();
255+
object.emplace("address", query.address_enabled());
256+
object.emplace("filter", query.filter_enabled());
257+
258+
send_json(std::move(model), 25);
259+
return true;
260+
}
261+
235262
bool protocol_explore::handle_get_top(const code& ec, interface::top,
236263
uint8_t, uint8_t media) NOEXCEPT
237264
{

test/parsers/explore_target.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,62 @@ BOOST_AUTO_TEST_CASE(parsers__explore_target__invalid_target__invalid_target)
6363
BOOST_REQUIRE_EQUAL(explore_target(out, "/v3/invalid"), server::error::invalid_target);
6464
}
6565

66+
// configuration
67+
68+
BOOST_AUTO_TEST_CASE(parsers__explore_target__configuration_valid__expected)
69+
{
70+
const std::string path = "/v42/configuration";
71+
72+
request_t request{};
73+
BOOST_REQUIRE(!explore_target(request, path));
74+
BOOST_REQUIRE_EQUAL(request.method, "configuration");
75+
BOOST_REQUIRE(request.params.has_value());
76+
77+
const auto& params = request.params.value();
78+
BOOST_REQUIRE(std::holds_alternative<object_t>(params));
79+
80+
const auto& object = std::get<object_t>(request.params.value());
81+
BOOST_REQUIRE_EQUAL(object.size(), 1u);
82+
83+
const auto version = std::get<uint8_t>(object.at("version").value());
84+
BOOST_REQUIRE_EQUAL(version, 42u);
85+
}
86+
87+
BOOST_AUTO_TEST_CASE(parsers__explore_target__configuration_extra_segment__extra_segment)
88+
{
89+
const std::string path = "/v3/configuration/extra";
90+
request_t out{};
91+
BOOST_REQUIRE_EQUAL(explore_target(out, path), server::error::extra_segment);
92+
}
93+
94+
// top
95+
96+
BOOST_AUTO_TEST_CASE(parsers__explore_target__top_valid__expected)
97+
{
98+
const std::string path = "/v42/top";
99+
100+
request_t request{};
101+
BOOST_REQUIRE(!explore_target(request, path));
102+
BOOST_REQUIRE_EQUAL(request.method, "top");
103+
BOOST_REQUIRE(request.params.has_value());
104+
105+
const auto& params = request.params.value();
106+
BOOST_REQUIRE(std::holds_alternative<object_t>(params));
107+
108+
const auto& object = std::get<object_t>(request.params.value());
109+
BOOST_REQUIRE_EQUAL(object.size(), 1u);
110+
111+
const auto version = std::get<uint8_t>(object.at("version").value());
112+
BOOST_REQUIRE_EQUAL(version, 42u);
113+
}
114+
115+
BOOST_AUTO_TEST_CASE(parsers__explore_target__top_extra_segment__extra_segment)
116+
{
117+
const std::string path = "/v3/top/extra";
118+
request_t out{};
119+
BOOST_REQUIRE_EQUAL(explore_target(out, path), server::error::extra_segment);
120+
}
121+
66122
// block/height
67123

68124
BOOST_AUTO_TEST_CASE(parsers__explore_target__block_height_valid__expected)

0 commit comments

Comments
 (0)