Skip to content

Commit 29ac4bf

Browse files
committed
Generalize electrum subscriptions.
1 parent e658252 commit 29ac4bf

11 files changed

Lines changed: 77 additions & 43 deletions

File tree

Makefile.am

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ src_libbitcoin_server_la_SOURCES = \
5757
src/protocols/electrum/protocol_electrum_mempool.cpp \
5858
src/protocols/electrum/protocol_electrum_outputs.cpp \
5959
src/protocols/electrum/protocol_electrum_scripthash.cpp \
60-
src/protocols/electrum/protocol_electrum_scripts.cpp \
60+
src/protocols/electrum/protocol_electrum_scriptpubkey.cpp \
6161
src/protocols/electrum/protocol_electrum_server.cpp \
6262
src/protocols/electrum/protocol_electrum_transactions.cpp \
6363
src/protocols/electrum/protocol_electrum_version.cpp \
@@ -105,7 +105,7 @@ test_libbitcoin_server_test_SOURCES = \
105105
test/protocols/electrum/electrum_mempool.cpp \
106106
test/protocols/electrum/electrum_outputs.cpp \
107107
test/protocols/electrum/electrum_scripthash.cpp \
108-
test/protocols/electrum/electrum_scripts.cpp \
108+
test/protocols/electrum/electrum_scriptpubkey.cpp \
109109
test/protocols/electrum/electrum_server.cpp \
110110
test/protocols/electrum/electrum_transactions.cpp \
111111
test/protocols/electrum/electrum_version.cpp \

builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_mempool.cpp" />
147147
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_outputs.cpp" />
148148
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scripthash.cpp" />
149-
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scripts.cpp" />
149+
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scriptpubkey.cpp" />
150150
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_server.cpp" />
151151
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_transactions.cpp" />
152152
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_version.cpp">

builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.vcxproj.filters

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scripthash.cpp">
8888
<Filter>src\protocols\electrum</Filter>
8989
</ClCompile>
90-
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scripts.cpp">
90+
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scriptpubkey.cpp">
9191
<Filter>src\protocols\electrum</Filter>
9292
</ClCompile>
9393
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_server.cpp">

builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_mempool.cpp" />
140140
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_outputs.cpp" />
141141
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scripthash.cpp" />
142-
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scripts.cpp" />
142+
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scriptpubkey.cpp" />
143143
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_server.cpp" />
144144
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_transactions.cpp" />
145145
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_version.cpp" />

builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj.filters

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scripthash.cpp">
118118
<Filter>src\protocols\electrum</Filter>
119119
</ClCompile>
120-
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scripts.cpp">
120+
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scriptpubkey.cpp">
121121
<Filter>src\protocols\electrum</Filter>
122122
</ClCompile>
123123
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_server.cpp">

include/bitcoin/server/protocols/protocol_electrum.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,10 @@ class BCS_API protocol_electrum
279279
array_t transform(const database::histories& histories) NOEXCEPT;
280280
array_t transform(const database::unspents& unspents) NOEXCEPT;
281281

282-
// Shared get_status implementation.
283-
bool send_get_status(const std::string& tx_hash, double txout_idx,
282+
// Shared implementations.
283+
void send_scripthash_unsubscribe(const system::hash_digest& hash) NOEXCEPT;
284+
void send_scripthash_subscribe(const system::hash_digest& hash) NOEXCEPT;
285+
bool send_get_status(const system::chain::point& prevout,
284286
const std::string& spk_hint) NOEXCEPT;
285287

286288
// These are thread safe.

src/protocols/electrum/protocol_electrum_addresses.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void protocol_electrum::handle_blockchain_address_list_unspent(const code& ec,
100100

101101
void protocol_electrum::handle_blockchain_address_subscribe(const code& ec,
102102
rpc_interface::blockchain_address_subscribe,
103-
const std::string& ) NOEXCEPT
103+
const std::string& address) NOEXCEPT
104104
{
105105
if (stopped(ec))
106106
return;
@@ -111,11 +111,14 @@ void protocol_electrum::handle_blockchain_address_subscribe(const code& ec,
111111
return;
112112
}
113113

114-
// TODO: collect the address into a limited notification set.
115-
subscribed_address_.store(true, std::memory_order_relaxed);
114+
const auto hash = extract_scripthash(address);
115+
if (hash == null_hash)
116+
{
117+
send_code(error::invalid_argument);
118+
return;
119+
}
116120

117-
// TODO: compute the status hash in a store query (no mempool).
118-
send_result(array_t{ string_t{ "status-hash" } }, 16, BIND(complete, _1));
121+
send_scripthash_subscribe(hash);
119122
}
120123

121124
// utilities

src/protocols/electrum/protocol_electrum_outputs.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,16 @@ void protocol_electrum::handle_blockchain_outpoint_get_status(const code& ec,
9494
return;
9595
}
9696

97-
send_get_status(tx_hash, txout_idx, spk_hint);
97+
uint32_t index{};
98+
hash_digest hash{};
99+
if (!to_integer(index, txout_idx) || !decode_hash(hash, tx_hash))
100+
{
101+
send_code(error::invalid_argument);
102+
return;
103+
}
104+
105+
chain::point prevout{ hash, index };
106+
send_get_status(prevout, spk_hint);
98107
}
99108

100109
void protocol_electrum::handle_blockchain_outpoint_subscribe(const code& ec,
@@ -110,10 +119,19 @@ void protocol_electrum::handle_blockchain_outpoint_subscribe(const code& ec,
110119
return;
111120
}
112121

113-
if (!send_get_status(tx_hash, txout_idx, spk_hint))
122+
uint32_t index{};
123+
hash_digest hash{};
124+
if (!to_integer(index, txout_idx) || !decode_hash(hash, tx_hash))
125+
{
126+
send_code(error::invalid_argument);
127+
return;
128+
}
129+
130+
chain::point prevout{ hash, index };
131+
if (!send_get_status(prevout, spk_hint))
114132
return;
115133

116-
// TODO: collect the outpoint into a limited notification set.
134+
// TODO: collect prevout into a limited notification set.
117135
subscribed_outpoint_.store(false, std::memory_order_relaxed);
118136
}
119137

@@ -139,7 +157,7 @@ void protocol_electrum::handle_blockchain_outpoint_unsubscribe(const code& ec,
139157
return;
140158
}
141159

142-
// TODO: remove outpoint subscription from notification set.
160+
// TODO: remove prevout subscription from notification set.
143161
chain::point prevout{ hash, index };
144162
const auto previous = subscribed_scriptpubkey_.load(
145163
std::memory_order_relaxed);
@@ -150,17 +168,9 @@ void protocol_electrum::handle_blockchain_outpoint_unsubscribe(const code& ec,
150168
// utility.
151169
// ----------------------------------------------------------------------------
152170

153-
bool protocol_electrum::send_get_status(const std::string& tx_hash,
154-
double txout_idx, const std::string& spk_hint) NOEXCEPT
171+
bool protocol_electrum::send_get_status(const chain::point& prevout,
172+
const std::string& spk_hint) NOEXCEPT
155173
{
156-
uint32_t index{};
157-
hash_digest hash{};
158-
if (!to_integer(index, txout_idx) || !decode_hash(hash, tx_hash))
159-
{
160-
send_code(error::invalid_argument);
161-
return false;
162-
}
163-
164174
// This is parsed for correctness but is not used.
165175
// Script is advisory, and should match output script.
166176
if (!spk_hint.empty())
@@ -181,14 +191,14 @@ bool protocol_electrum::send_get_status(const std::string& tx_hash,
181191
}
182192

183193
const auto& query = archive();
184-
const auto out = query.get_tx_history(hash);
194+
const auto out = query.get_tx_history(prevout.hash());
185195
if (!out.tx.is_valid())
186196
{
187197
send_code(error::not_found);
188198
return false;
189199
}
190200

191-
if (const auto ins = query.get_spenders_history(hash, index); ins.empty())
201+
if (const auto ins = query.get_spenders_history(prevout); ins.empty())
192202
{
193203
send_result(object_t
194204
{

src/protocols/electrum/protocol_electrum_scripthash.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ void protocol_electrum::complete_list_unspent(const code& ec,
318318

319319
void protocol_electrum::handle_blockchain_scripthash_subscribe(const code& ec,
320320
rpc_interface::blockchain_scripthash_subscribe,
321-
const std::string& ) NOEXCEPT
321+
const std::string& scripthash) NOEXCEPT
322322
{
323323
if (stopped(ec))
324324
return;
@@ -329,7 +329,21 @@ void protocol_electrum::handle_blockchain_scripthash_subscribe(const code& ec,
329329
return;
330330
}
331331

332-
// TODO: collect the scripthash into a limited notification set.
332+
hash_digest hash{};
333+
if (!decode_hash(hash, scripthash))
334+
{
335+
send_code(error::invalid_argument);
336+
return;
337+
}
338+
339+
send_scripthash_subscribe(hash);
340+
}
341+
342+
void protocol_electrum::send_scripthash_subscribe(
343+
const hash_digest& ) NOEXCEPT
344+
{
345+
346+
// TODO: collect hash into a limited notification set.
333347
subscribed_scripthash_.store(true, std::memory_order_relaxed);
334348

335349
// TODO: compute the status hash in a store query (no mempool).
@@ -338,7 +352,7 @@ void protocol_electrum::handle_blockchain_scripthash_subscribe(const code& ec,
338352

339353
void protocol_electrum::handle_blockchain_scripthash_unsubscribe(const code& ec,
340354
rpc_interface::blockchain_scripthash_unsubscribe,
341-
const std::string& ) NOEXCEPT
355+
const std::string& scripthash) NOEXCEPT
342356
{
343357
if (stopped(ec))
344358
return;
@@ -349,7 +363,20 @@ void protocol_electrum::handle_blockchain_scripthash_unsubscribe(const code& ec,
349363
return;
350364
}
351365

352-
// TODO: remove scripthash subscription from the notification set.
366+
hash_digest hash{};
367+
if (!decode_hash(hash, scripthash))
368+
{
369+
send_code(error::invalid_argument);
370+
return;
371+
}
372+
373+
send_scripthash_unsubscribe(hash);
374+
}
375+
376+
void protocol_electrum::send_scripthash_unsubscribe(
377+
const hash_digest& ) NOEXCEPT
378+
{
379+
// TODO: remove hash subscription from the notification set.
353380
const auto previous = subscribed_scriptpubkey_.load(
354381
std::memory_order_relaxed);
355382

src/protocols/electrum/protocol_electrum_scripts.cpp renamed to src/protocols/electrum/protocol_electrum_scriptpubkey.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,7 @@ void protocol_electrum::handle_blockchain_scriptpubkey_subscribe(
181181
return;
182182
}
183183

184-
// TODO: collect the address into a limited notification set.
185-
subscribed_address_.store(true, std::memory_order_relaxed);
186-
187-
// TODO: compute the status hash in a store query (no mempool).
188-
send_result(object_t{}, 16, BIND(complete, _1));
184+
send_scripthash_subscribe(script.hash());
189185
}
190186

191187
void protocol_electrum::handle_blockchain_scriptpubkey_unsubscribe(
@@ -215,11 +211,7 @@ void protocol_electrum::handle_blockchain_scriptpubkey_unsubscribe(
215211
return;
216212
}
217213

218-
// TODO: remove script subscription from notification set.
219-
const auto previous = subscribed_scriptpubkey_.load(
220-
std::memory_order_relaxed);
221-
222-
send_result(previous, 16, BIND(complete, _1));
214+
send_scripthash_unsubscribe(script.hash());
223215
}
224216

225217
BC_POP_WARNING()

0 commit comments

Comments
 (0)