Skip to content

Commit 8c6c658

Browse files
authored
Merge pull request #704 from evoskuil/master
Implement electrum address history status hashing, style.
2 parents 36bc3de + 87a1988 commit 8c6c658

3 files changed

Lines changed: 43 additions & 34 deletions

File tree

include/bitcoin/server/protocols/protocol_electrum.hpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ class BCS_API protocol_electrum
204204
rpc_interface::mempool_get_info) NOEXCEPT;
205205

206206
protected:
207+
using unspents = database::unspents;
208+
using histories = database::histories;
207209
using hash_digest = system::hash_digest;
208210
enum class notify_t { address, scripthash, scriptpubkey };
209211
typedef std::function<void(const code&, const hash_digest&,
@@ -231,11 +233,11 @@ class BCS_API protocol_electrum
231233
void complete_get_balance(const code& ec, uint64_t confirmed,
232234
int64_t unconfirmed) NOEXCEPT;
233235
void complete_get_history(const code& ec,
234-
const database::histories& histories) NOEXCEPT;
236+
const histories& histories) NOEXCEPT;
235237
void complete_get_mempool(const code& ec,
236-
const database::histories& histories) NOEXCEPT;
238+
const histories& histories) NOEXCEPT;
237239
void complete_list_unspent(const code& ec,
238-
const database::unspents& unspents) NOEXCEPT;
240+
const unspents& unspents) NOEXCEPT;
239241
void complete_status(const code& ec, const hash_digest& hash,
240242
const hash_digest& status, const status_handler& sender) NOEXCEPT;
241243

@@ -282,10 +284,11 @@ class BCS_API protocol_electrum
282284
static constexpr electrum::version minimum = version_t::minimum;
283285
static constexpr electrum::version maximum = version_t::maximum;
284286

285-
// Address transformations.
286-
static array_t transform(const database::histories& histories) NOEXCEPT;
287-
static array_t transform(const database::unspents& unspents) NOEXCEPT;
287+
// Transformations.
288288
static std::string to_method_name(notify_t type) NOEXCEPT;
289+
static array_t transform(const unspents& unspents) NOEXCEPT;
290+
static array_t transform(const histories& histories) NOEXCEPT;
291+
static hash_digest to_status(const histories& histories) NOEXCEPT;
289292

290293
// Compute server.features.hosts value from config.
291294
object_t self_hosts() const NOEXCEPT;

src/protocols/electrum/protocol_electrum_outputs.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ void protocol_electrum::handle_blockchain_utxo_get_address(const code& ec,
4747

4848
uint32_t offset{};
4949
hash_digest hash{};
50-
if (!to_integer(offset, index) ||
51-
!decode_hash(hash, tx_hash))
50+
if (!to_integer(offset, index) || !decode_hash(hash, tx_hash))
5251
{
5352
send_code(error::invalid_argument);
5453
return;
@@ -152,8 +151,7 @@ void protocol_electrum::handle_blockchain_outpoint_unsubscribe(const code& ec,
152151

153152
uint32_t index{};
154153
hash_digest hash{};
155-
if (!to_integer(index, txout_idx) ||
156-
!decode_hash(hash, tx_hash))
154+
if (!to_integer(index, txout_idx) || !decode_hash(hash, tx_hash))
157155
{
158156
send_code(error::invalid_argument);
159157
return;

src/protocols/electrum/protocol_electrum_scripthash.cpp

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,14 @@ void protocol_electrum::do_get_history(const hash_digest& hash) NOEXCEPT
151151
{
152152
BC_ASSERT(!stranded());
153153

154+
histories histories{};
154155
const auto& query = archive();
155-
database::histories histories{};
156156
const auto ec = query.get_history(stopping_, histories, hash, turbo_);
157157
POST(complete_get_history, ec, std::move(histories));
158158
}
159159

160160
void protocol_electrum::complete_get_history(const code& ec,
161-
const database::histories& histories) NOEXCEPT
161+
const histories& histories) NOEXCEPT
162162
{
163163
BC_ASSERT(stranded());
164164

@@ -220,14 +220,14 @@ void protocol_electrum::do_get_mempool(const hash_digest& hash) NOEXCEPT
220220
{
221221
BC_ASSERT(!stranded());
222222

223+
histories histories{};
223224
const auto& query = archive();
224-
database::histories histories{};
225225
auto ec = query.get_unconfirmed_history(stopping_, histories, hash, turbo_);
226226
POST(complete_get_mempool, ec, std::move(histories));
227227
}
228228

229229
void protocol_electrum::complete_get_mempool(const code& ec,
230-
const database::histories& histories) NOEXCEPT
230+
const histories& histories) NOEXCEPT
231231
{
232232
BC_ASSERT(stranded());
233233

@@ -288,14 +288,14 @@ void protocol_electrum::do_list_unspent(const hash_digest& hash) NOEXCEPT
288288
{
289289
BC_ASSERT(!stranded());
290290

291+
unspents unspents{};
291292
const auto& query = archive();
292-
database::unspents unspents{};
293293
const auto ec = query.get_unspent(stopping_, unspents, hash, turbo_);
294294
POST(complete_list_unspent, ec, std::move(unspents));
295295
}
296296

297297
void protocol_electrum::complete_list_unspent(const code& ec,
298-
const database::unspents& unspents) NOEXCEPT
298+
const unspents& unspents) NOEXCEPT
299299
{
300300
BC_ASSERT(stranded());
301301

@@ -361,19 +361,10 @@ void protocol_electrum::do_status(const hash_digest& hash,
361361
subscribed_scripthash_.store(true, std::memory_order_relaxed);
362362
///////////////////////////////////////////////////////////////////////////
363363

364-
hash_digest status{};
364+
histories histories{};
365365
const auto& query = archive();
366-
database::histories histories{};
367366
const auto ec = query.get_history(stopping_, histories, hash, turbo_);
368-
369-
// TODO: compute status hash and initialize/update associated midstate.
370-
///////////////////////////////////////////////////////////////////////////
371-
if (!ec && !histories.empty())
372-
{
373-
}
374-
///////////////////////////////////////////////////////////////////////////
375-
376-
POST(complete_status, ec, hash, std::move(status), sender);
367+
POST(complete_status, ec, hash, to_status(histories), sender);
377368
}
378369

379370
void protocol_electrum::complete_status(const code& ec,
@@ -446,13 +437,31 @@ void protocol_electrum::send_scripthash_unsubscribe(
446437

447438
// utilities
448439
// ----------------------------------------------------------------------------
440+
// TODO: these can be implemented as electrum json serializers (see bitcoind).
449441
// private/static
450442

451-
// Height is set to 0 for unconfirmed tx fully chain rooted and -1 otherwise.
452-
// TODO: this can be implemented as electrum json serializers (see bitcoind).
453-
array_t protocol_electrum::transform(const database::histories& ins) NOEXCEPT
443+
// Height is zero (rooted) or max_size_t for unconfirmed history txs.
444+
hash_digest protocol_electrum::to_status(const histories& histories) NOEXCEPT
445+
{
446+
if (histories.empty())
447+
return {};
448+
449+
midstate out{};
450+
for (const auto& record: histories)
451+
{
452+
out.writer.write_string(encode_hash(record.tx.hash()));
453+
out.writer.write_string(":");
454+
out.writer.write_string(std::to_string(to_signed(record.tx.height())));
455+
out.writer.write_string(":");
456+
}
457+
458+
out.writer.flush();
459+
return out.status;
460+
}
461+
462+
// Height is zero (rooted) or max_size_t for unconfirmed history txs.
463+
array_t protocol_electrum::transform(const histories& ins) NOEXCEPT
454464
{
455-
// Height is set to zero or max_size_t for unconfirmed history.
456465
// to_signed() conversion is simple but sacrifices top height bit (ok).
457466
static_assert(to_signed(max_size_t) == -1 && is_max(max_size_t));
458467

@@ -481,9 +490,8 @@ array_t protocol_electrum::transform(const database::histories& ins) NOEXCEPT
481490
return out;
482491
}
483492

484-
// Height is set to 0 for unconfirmed unspent output txs.
485-
// TODO: this can be implemented as electrum json serializers (see bitcoind).
486-
array_t protocol_electrum::transform(const database::unspents& ins) NOEXCEPT
493+
// Height is zero for unconfirmed unspent output txs.
494+
array_t protocol_electrum::transform(const unspents& ins) NOEXCEPT
487495
{
488496
array_t out(ins.size());
489497
std::ranges::transform(ins, out.begin(), [](const auto& in) NOEXCEPT

0 commit comments

Comments
 (0)