Skip to content

Commit b057845

Browse files
authored
Merge pull request #646 from evoskuil/master
Differentiate multiplicity in block_header/s returns.
2 parents 322bd0f + 99b4dd1 commit b057845

File tree

2 files changed

+44
-26
lines changed

2 files changed

+44
-26
lines changed

include/bitcoin/server/protocols/protocol_electrum.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ class BCS_API protocol_electrum
123123
rpc_interface::mempool_get_fee_histogram) NOEXCEPT;
124124

125125
protected:
126+
/// Common implementation for block_header/s.
127+
void blockchain_block_headers(size_t starting, size_t quantity,
128+
size_t waypoint, bool multiplicity) NOEXCEPT;
129+
126130
inline bool is_version(electrum_version version) const NOEXCEPT
127131
{
128132
return channel_->version() >= version;

src/protocols/protocol_electrum.cpp

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,20 @@ void protocol_electrum::handle_blockchain_block_header(const code& ec,
137137
rpc_interface::blockchain_block_header, double height,
138138
double cp_height) NOEXCEPT
139139
{
140-
handle_blockchain_block_headers(ec, {}, height, 1, cp_height);
140+
using namespace system;
141+
if (stopped(ec))
142+
return;
143+
144+
size_t starting{};
145+
size_t waypoint{};
146+
if (!to_integer(starting, height) ||
147+
!to_integer(waypoint, cp_height))
148+
{
149+
send_code(error::invalid_argument);
150+
return;
151+
}
152+
153+
blockchain_block_headers(starting, one, waypoint, false);
141154
}
142155

143156
void protocol_electrum::handle_blockchain_block_headers(const code& ec,
@@ -159,6 +172,14 @@ void protocol_electrum::handle_blockchain_block_headers(const code& ec,
159172
return;
160173
}
161174

175+
blockchain_block_headers(starting, quantity, waypoint, true);
176+
}
177+
178+
// Common implementation for block_header/s.
179+
void protocol_electrum::blockchain_block_headers(size_t starting,
180+
size_t quantity, size_t waypoint, bool multiplicity) NOEXCEPT
181+
{
182+
using namespace system;
162183
if (is_add_overflow(starting, quantity))
163184
{
164185
send_code(error::argument_overflow);
@@ -182,8 +203,8 @@ void protocol_electrum::handle_blockchain_block_headers(const code& ec,
182203
// Returned headers are assured to be contiguous despite intervening reorg.
183204
// No headers may be returned, which implies start > confirmed top block.
184205
const auto& query = archive();
185-
const auto bound = limit(quantity, maximum);
186-
const auto links = query.get_confirmed_headers(starting, bound);
206+
const auto count = limit(quantity, maximum);
207+
const auto links = query.get_confirmed_headers(starting, count);
187208
constexpr auto header_size = chain::header::serialized_size();
188209
auto size = two * header_size * links.size();
189210

@@ -194,33 +215,27 @@ void protocol_electrum::handle_blockchain_block_headers(const code& ec,
194215
{
195216
if (const auto header = query.get_header(link); header)
196217
{
197-
// TODO: optimize by query directly returning wire serialization.
198218
headers.push_back(to_hex(*header, header_size));
219+
continue;
199220
}
200-
else
201-
{
202-
send_code(error::server_error);
203-
return;
204-
}
221+
222+
send_code(error::server_error);
223+
return;
205224
};
206225

207-
value_t value
226+
value_t value{};
227+
auto& result = std::get<object_t>(value.value());
228+
if (multiplicity)
208229
{
209-
object_t
210-
{
211-
{ "count", uint64_t{ quantity } },
212-
{ "headers", std::move(headers) },
213-
{ "max", maximum }
214-
}
215-
216-
// BUGBUG: for handle_blockchain_block_header:
217-
////object_t
218-
////{
219-
//// { "header", headers.front() },
220-
////}
221-
};
230+
result["headers"] = std::move(headers);
231+
result["count"] = uint64_t{ quantity };
232+
result["max"] = maximum;
233+
}
234+
else
235+
{
236+
result["header"] = headers.front();
237+
}
222238

223-
// BUGBUG: difference in get_merkle_root_and_proof vs. electrumx.
224239
// There is a very slim change of inconsistency given an intervening reorg
225240
// because of get_merkle_root_and_proof() use of height-based calculations.
226241
// This is acceptable as it must be verified by caller in any case.
@@ -239,9 +254,8 @@ void protocol_electrum::handle_blockchain_block_headers(const code& ec,
239254
std::ranges::transform(proof, branch.begin(),
240255
[](const auto& hash) { return encode_base16(hash); });
241256

242-
auto& result = std::get<object_t>(value.value());
243-
result["root"] = encode_base16(root);
244257
result["branch"] = std::move(branch);
258+
result["root"] = encode_base16(root);
245259
size += two * hash_size * add1(proof.size());
246260
}
247261

0 commit comments

Comments
 (0)