Skip to content

Commit 31e1553

Browse files
authored
Merge pull request #901 from evoskuil/master
Extend and revise explore interface, stub new methods.
2 parents 98499c1 + b1445bb commit 31e1553

File tree

4 files changed

+548
-407
lines changed

4 files changed

+548
-407
lines changed

include/bitcoin/node/protocols/protocol_explore.hpp

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,47 @@ class BCN_API protocol_explore
6060

6161
/// REST interface handlers.
6262

63+
bool handle_get_top(const code& ec, interface::top,
64+
uint8_t version, uint8_t media) NOEXCEPT;
65+
6366
bool handle_get_block(const code& ec, interface::block,
6467
uint8_t version, uint8_t media, std::optional<system::hash_cptr> hash,
6568
std::optional<uint32_t> height, bool witness) NOEXCEPT;
66-
bool handle_get_header(const code& ec, interface::header,
69+
bool handle_get_block_header(const code& ec, interface::block_header,
6770
uint8_t version, uint8_t media, std::optional<system::hash_cptr> hash,
6871
std::optional<uint32_t> height) NOEXCEPT;
6972
bool handle_get_block_txs(const code& ec, interface::block_txs,
7073
uint8_t version, uint8_t media, std::optional<system::hash_cptr> hash,
7174
std::optional<uint32_t> height) NOEXCEPT;
75+
bool handle_get_block_fees(const code& ec, interface::block_fees,
76+
uint8_t version, uint8_t media, std::optional<system::hash_cptr> hash,
77+
std::optional<uint32_t> height) NOEXCEPT;
78+
bool handle_get_block_filter(const code& ec, interface::block_filter,
79+
uint8_t version, uint8_t media, uint8_t type,
80+
std::optional<system::hash_cptr> hash,
81+
std::optional<uint32_t> height) NOEXCEPT;
82+
bool handle_get_block_filter_hash(const code& ec,
83+
interface::block_filter_hash, uint8_t version, uint8_t media,
84+
uint8_t type, std::optional<system::hash_cptr> hash,
85+
std::optional<uint32_t> height) NOEXCEPT;
86+
bool handle_get_block_filter_header(const code& ec,
87+
interface::block_filter_header, uint8_t version, uint8_t media,
88+
uint8_t type, std::optional<system::hash_cptr> hash,
89+
std::optional<uint32_t> height) NOEXCEPT;
7290
bool handle_get_block_tx(const code& ec, interface::block_tx,
7391
uint8_t version, uint8_t media, uint32_t position,
7492
std::optional<system::hash_cptr> hash,
7593
std::optional<uint32_t> height, bool witness) NOEXCEPT;
76-
bool handle_get_transaction(const code& ec, interface::transaction,
94+
95+
bool handle_get_tx(const code& ec, interface::tx,
7796
uint8_t version, uint8_t media, const system::hash_cptr& hash,
7897
bool witness) NOEXCEPT;
7998
bool handle_get_tx_block(const code& ec, interface::tx_block,
8099
uint8_t version, uint8_t media,
81100
const system::hash_cptr& hash) NOEXCEPT;
101+
bool handle_get_tx_fee(const code& ec, interface::tx_fee,
102+
uint8_t version, uint8_t media,
103+
const system::hash_cptr& hash) NOEXCEPT;
82104

83105
bool handle_get_inputs(const code& ec, interface::inputs,
84106
uint8_t version, uint8_t media, const system::hash_cptr& hash,
@@ -112,19 +134,20 @@ class BCN_API protocol_explore
112134
bool handle_get_address(const code& ec, interface::address,
113135
uint8_t version, uint8_t media,
114136
const system::hash_cptr& hash) NOEXCEPT;
115-
bool handle_get_filter(const code& ec, interface::filter, uint8_t version,
116-
uint8_t media, uint8_t type, std::optional<system::hash_cptr> hash,
117-
std::optional<uint32_t> height) NOEXCEPT;
118-
bool handle_get_filter_hash(const code& ec, interface::filter_hash,
119-
uint8_t version, uint8_t media, uint8_t type,
120-
std::optional<system::hash_cptr> hash,
121-
std::optional<uint32_t> height) NOEXCEPT;
122-
bool handle_get_filter_header(const code& ec, interface::filter_header,
123-
uint8_t version, uint8_t media, uint8_t type,
124-
std::optional<system::hash_cptr> hash,
125-
std::optional<uint32_t> height) NOEXCEPT;
137+
bool handle_get_address_confirmed(const code& ec,
138+
interface::address_confirmed, uint8_t version, uint8_t media,
139+
const system::hash_cptr& hash) NOEXCEPT;
140+
bool handle_get_address_unconfirmed(const code& ec,
141+
interface::address_unconfirmed, uint8_t version, uint8_t media,
142+
const system::hash_cptr& hash) NOEXCEPT;
143+
bool handle_get_address_balance(const code& ec,
144+
interface::address_balance, uint8_t version, uint8_t media,
145+
const system::hash_cptr& hash) NOEXCEPT;
126146

127147
private:
148+
void inject(boost::json::value& out, std::optional<uint32_t> height,
149+
const database::header_link& link) const NOEXCEPT;
150+
128151
database::header_link to_header(const std::optional<uint32_t>& height,
129152
const std::optional<system::hash_cptr>& hash) NOEXCEPT;
130153

src/parse/target.cpp

Lines changed: 69 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ static hash_cptr to_hash(const std::string_view& token) NOEXCEPT
4646
emplace_shared<const hash_digest>(std::move(out)) : hash_cptr{};
4747
}
4848

49+
static hash_cptr to_base16(const std::string_view& token) NOEXCEPT
50+
{
51+
hash_digest out{};
52+
return decode_base16(out, token) ?
53+
emplace_shared<const hash_digest>(std::move(out)) : hash_cptr{};
54+
}
55+
4956
code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
5057
{
5158
const auto clean = split(path, "?", false, false).front();
@@ -84,38 +91,21 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
8491
// transaction, address, inputs, and outputs are identical excluding names;
8592
// input and output are identical excluding names; block is unique.
8693
const auto target = segments[segment++];
87-
if (target == "address")
94+
if (target == "top")
8895
{
89-
if (segment == segments.size())
90-
return error::missing_hash;
91-
92-
const auto hash = to_hash(segments[segment++]);
93-
if (!hash) return error::invalid_hash;
94-
95-
method = "address";
96-
params["hash"] = hash;
96+
method = "top";
9797
}
98-
else if (target == "inputs")
98+
else if (target == "address")
9999
{
100100
if (segment == segments.size())
101101
return error::missing_hash;
102102

103-
const auto hash = to_hash(segments[segment++]);
104-
if (!hash) return error::invalid_hash;
105-
106-
method = "inputs";
107-
params["hash"] = hash;
108-
}
109-
else if (target == "outputs")
110-
{
111-
if (segment == segments.size())
112-
return error::missing_hash;
113-
114-
const auto hash = to_hash(segments[segment++]);
115-
if (!hash) return error::invalid_hash;
103+
// address hash is a single sha256, and conventionally not reversed.
104+
const auto base16 = to_base16(segments[segment++]);
105+
if (!base16) return error::invalid_hash;
116106

117-
method = "outputs";
118-
params["hash"] = hash;
107+
method = "address";
108+
params["hash"] = base16;
119109
}
120110
else if (target == "input")
121111
{
@@ -126,28 +116,32 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
126116
if (!hash) return error::invalid_hash;
127117

128118
params["hash"] = hash;
129-
if (segment == segments.size())
130-
return error::missing_component;
131-
132-
const auto component = segments[segment++];
133-
uint32_t index{};
134-
if (!to_number(index, component))
135-
return error::invalid_number;
136-
137-
params["index"] = index;
138119
if (segment == segments.size())
139120
{
140-
method = "input";
121+
method = "inputs";
141122
}
142123
else
143124
{
144-
const auto subcomponent = segments[segment++];
145-
if (subcomponent == "script")
146-
method = "input_script";
147-
else if (subcomponent == "witness")
148-
method = "input_witness";
125+
const auto component = segments[segment++];
126+
uint32_t index{};
127+
if (!to_number(index, component))
128+
return error::invalid_number;
129+
130+
params["index"] = index;
131+
if (segment == segments.size())
132+
{
133+
method = "input";
134+
}
149135
else
150-
return error::invalid_subcomponent;
136+
{
137+
const auto subcomponent = segments[segment++];
138+
if (subcomponent == "script")
139+
method = "input_script";
140+
else if (subcomponent == "witness")
141+
method = "input_witness";
142+
else
143+
return error::invalid_subcomponent;
144+
}
151145
}
152146
}
153147
else if (target == "output")
@@ -159,33 +153,37 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
159153
if (!hash) return error::invalid_hash;
160154

161155
params["hash"] = hash;
162-
if (segment == segments.size())
163-
return error::missing_component;
164-
165-
const auto component = segments[segment++];
166-
uint32_t index{};
167-
if (!to_number(index, component))
168-
return error::invalid_number;
169-
170-
params["index"] = index;
171156
if (segment == segments.size())
172157
{
173-
method = "output";
158+
method = "outputs";
174159
}
175160
else
176161
{
177-
const auto subcomponent = segments[segment++];
178-
if (subcomponent == "script")
179-
method = "output_script";
180-
else if (subcomponent == "spender")
181-
method = "output_spender";
182-
else if (subcomponent == "spenders")
183-
method = "output_spenders";
162+
const auto component = segments[segment++];
163+
uint32_t index{};
164+
if (!to_number(index, component))
165+
return error::invalid_number;
166+
167+
params["index"] = index;
168+
if (segment == segments.size())
169+
{
170+
method = "output";
171+
}
184172
else
185-
return error::invalid_subcomponent;
173+
{
174+
const auto subcomponent = segments[segment++];
175+
if (subcomponent == "script")
176+
method = "output_script";
177+
else if (subcomponent == "spender")
178+
method = "output_spender";
179+
else if (subcomponent == "spenders")
180+
method = "output_spenders";
181+
else
182+
return error::invalid_subcomponent;
183+
}
186184
}
187185
}
188-
else if (target == "transaction")
186+
else if (target == "tx")
189187
{
190188
if (segment == segments.size())
191189
return error::missing_hash;
@@ -196,13 +194,15 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
196194
params["hash"] = hash;
197195
if (segment == segments.size())
198196
{
199-
method = "transaction";
197+
method = "tx";
200198
}
201199
else
202200
{
203201
const auto component = segments[segment++];
204202
if (component == "block")
205203
method = "tx_block";
204+
else if (component == "fee")
205+
method = "tx_fee";
206206
else
207207
return error::invalid_component;
208208
}
@@ -221,8 +221,6 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
221221
const auto hash = to_hash(segments[segment++]);
222222
if (!hash) return error::invalid_hash;
223223

224-
// nullables can be implicit.
225-
////params["height"] = null_t{};
226224
params["hash"] = hash;
227225
}
228226
else if (by == "height")
@@ -234,8 +232,6 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
234232
if (!to_number(height, segments[segment++]))
235233
return error::invalid_number;
236234

237-
// nullables can be implicit.
238-
////params["hash"] = null_t{};
239235
params["height"] = height;
240236
}
241237
else
@@ -250,7 +246,7 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
250246
else
251247
{
252248
const auto component = segments[segment++];
253-
if (component == "transaction")
249+
if (component == "tx")
254250
{
255251
if (segment == segments.size())
256252
return error::missing_position;
@@ -263,9 +259,11 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
263259
method = "block_tx";
264260
}
265261
else if (component == "header")
266-
method = "header";
267-
else if (component == "transactions")
262+
method = "block_header";
263+
else if (component == "txs")
268264
method = "block_txs";
265+
else if (component == "fees")
266+
method = "block_fees";
269267
else if (component == "filter")
270268
{
271269
if (segment == segments.size())
@@ -278,15 +276,15 @@ code parse_target(request_t& out, const std::string_view& path) NOEXCEPT
278276
params["type"] = type;
279277
if (segment == segments.size())
280278
{
281-
method = "filter";
279+
method = "block_filter";
282280
}
283281
else
284282
{
285283
const auto subcomponent = segments[segment++];
286284
if (subcomponent == "hash")
287-
method = "filter_hash";
285+
method = "block_filter_hash";
288286
else if (subcomponent == "header")
289-
method = "filter_header";
287+
method = "block_filter_header";
290288
else
291289
return error::invalid_subcomponent;
292290
}

0 commit comments

Comments
 (0)