Skip to content

Commit 3025228

Browse files
authored
Merge pull request #690 from evoskuil/master
Stub in tentative electrum 1.7 protocol additions.
2 parents 22b655b + 600632d commit 3025228

16 files changed

Lines changed: 797 additions & 187 deletions

Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ src_libbitcoin_server_la_SOURCES = \
5555
src/protocols/electrum/protocol_electrum_fees.cpp \
5656
src/protocols/electrum/protocol_electrum_headers.cpp \
5757
src/protocols/electrum/protocol_electrum_mempool.cpp \
58+
src/protocols/electrum/protocol_electrum_outputs.cpp \
5859
src/protocols/electrum/protocol_electrum_scripthash.cpp \
60+
src/protocols/electrum/protocol_electrum_scripts.cpp \
5961
src/protocols/electrum/protocol_electrum_server.cpp \
6062
src/protocols/electrum/protocol_electrum_transactions.cpp \
6163
src/protocols/electrum/protocol_electrum_version.cpp \
@@ -101,7 +103,9 @@ test_libbitcoin_server_test_SOURCES = \
101103
test/protocols/electrum/electrum_fees.cpp \
102104
test/protocols/electrum/electrum_headers.cpp \
103105
test/protocols/electrum/electrum_mempool.cpp \
106+
test/protocols/electrum/electrum_outputs.cpp \
104107
test/protocols/electrum/electrum_scripthash.cpp \
108+
test/protocols/electrum/electrum_scripts.cpp \
105109
test/protocols/electrum/electrum_server.cpp \
106110
test/protocols/electrum/electrum_transactions.cpp \
107111
test/protocols/electrum/electrum_version.cpp \

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@
144144
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_fees.cpp" />
145145
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_headers.cpp" />
146146
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_mempool.cpp" />
147+
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_outputs.cpp" />
147148
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scripthash.cpp" />
149+
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scripts.cpp" />
148150
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_server.cpp" />
149151
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_transactions.cpp" />
150152
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_version.cpp">

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,15 @@
8181
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_mempool.cpp">
8282
<Filter>src\protocols\electrum</Filter>
8383
</ClCompile>
84+
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_outputs.cpp">
85+
<Filter>src\protocols\electrum</Filter>
86+
</ClCompile>
8487
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scripthash.cpp">
8588
<Filter>src\protocols\electrum</Filter>
8689
</ClCompile>
90+
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_scripts.cpp">
91+
<Filter>src\protocols\electrum</Filter>
92+
</ClCompile>
8793
<ClCompile Include="..\..\..\..\test\protocols\electrum\electrum_server.cpp">
8894
<Filter>src\protocols\electrum</Filter>
8995
</ClCompile>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,9 @@
137137
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_fees.cpp" />
138138
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_headers.cpp" />
139139
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_mempool.cpp" />
140+
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_outputs.cpp" />
140141
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scripthash.cpp" />
142+
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scripts.cpp" />
141143
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_server.cpp" />
142144
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_transactions.cpp" />
143145
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_version.cpp" />

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,15 @@
111111
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_mempool.cpp">
112112
<Filter>src\protocols\electrum</Filter>
113113
</ClCompile>
114+
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_outputs.cpp">
115+
<Filter>src\protocols\electrum</Filter>
116+
</ClCompile>
114117
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scripthash.cpp">
115118
<Filter>src\protocols\electrum</Filter>
116119
</ClCompile>
120+
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_scripts.cpp">
121+
<Filter>src\protocols\electrum</Filter>
122+
</ClCompile>
117123
<ClCompile Include="..\..\..\..\src\protocols\electrum\protocol_electrum_server.cpp">
118124
<Filter>src\protocols\electrum</Filter>
119125
</ClCompile>

include/bitcoin/server/interfaces/electrum.hpp

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ struct electrum_methods
4343
method<"blockchain.relayfee">{},
4444

4545
method<"blockchain.utxo.get_address", string_t, number_t>{ "tx_hash", "index" },
46+
method<"blockchain.outpoint.get_status", string_t, number_t, optional<""_t>>{ "tx_hash", "txout_idx", "spk_hint" },
47+
method<"blockchain.outpoint.subscribe", string_t, number_t, optional<""_t>>{ "tx_hash", "txout_idx", "spk_hint" },
48+
method<"blockchain.outpoint.unsubscribe", string_t, number_t>{ "tx_hash", "txout_idx" },
49+
4650
method<"blockchain.address.get_balance", string_t>{ "address" },
4751
method<"blockchain.address.get_history", string_t>{ "address" },
4852
method<"blockchain.address.get_mempool", string_t>{ "address" },
@@ -56,6 +60,13 @@ struct electrum_methods
5660
method<"blockchain.scripthash.subscribe", string_t>{ "scripthash" },
5761
method<"blockchain.scripthash.unsubscribe", string_t>{ "scripthash" },
5862

63+
method<"blockchain.scriptpubkey.get_balance", string_t>{ "scriptpubkey" },
64+
method<"blockchain.scriptpubkey.get_history", string_t>{ "scriptpubkey" },
65+
method<"blockchain.scriptpubkey.get_mempool", string_t>{ "scriptpubkey" },
66+
method<"blockchain.scriptpubkey.listunspent", string_t>{ "scriptpubkey" },
67+
method<"blockchain.scriptpubkey.subscribe", string_t>{ "scriptpubkey" },
68+
method<"blockchain.scriptpubkey.unsubscribe", string_t>{ "scriptpubkey" },
69+
5970
method<"blockchain.transaction.broadcast", string_t>{ "raw_tx" },
6071
method<"blockchain.transaction.broadcast_package", value_t, optional<false>>{ "raw_txs", "verbose" },
6172
method<"blockchain.transaction.get", string_t, boolean_t>{ "tx_hash", "verbose" },
@@ -93,35 +104,46 @@ struct electrum_methods
93104
using blockchain_relay_fee = at<7>;
94105

95106
using blockchain_utxo_get_address = at<8>;
96-
using blockchain_address_get_balance = at<9>;
97-
using blockchain_address_get_history = at<10>;
98-
using blockchain_address_get_mempool = at<11>;
99-
using blockchain_address_list_unspent = at<12>;
100-
using blockchain_address_subscribe = at<13>;
101-
102-
using blockchain_scripthash_get_balance = at<14>;
103-
using blockchain_scripthash_get_history = at<15>;
104-
using blockchain_scripthash_get_mempool = at<16>;
105-
using blockchain_scripthash_list_unspent = at<17>;
106-
using blockchain_scripthash_subscribe = at<18>;
107-
using blockchain_scripthash_unsubscribe = at<19>;
108-
109-
using blockchain_transaction_broadcast = at<20>;
110-
using blockchain_transaction_broadcast_package = at<21>;
111-
using blockchain_transaction_get = at<22>;
112-
using blockchain_transaction_get_merkle = at<23>;
113-
using blockchain_transaction_id_from_position = at<24>;
114-
115-
using server_add_peer = at<25>;
116-
using server_banner = at<26>;
117-
using server_donation_address = at<27>;
118-
using server_features = at<28>;
119-
using server_peers_subscribe = at<29>;
120-
using server_ping = at<30>;
121-
using server_version = at<31>;
122-
123-
using mempool_get_fee_histogram = at<32>;
124-
using mempool_get_info = at<33>;
107+
using blockchain_outpoint_get_status = at<9>;
108+
using blockchain_outpoint_subscribe = at<10>;
109+
using blockchain_outpoint_unsubscribe = at<11>;
110+
111+
using blockchain_address_get_balance = at<12>;
112+
using blockchain_address_get_history = at<13>;
113+
using blockchain_address_get_mempool = at<14>;
114+
using blockchain_address_list_unspent = at<15>;
115+
using blockchain_address_subscribe = at<16>;
116+
117+
using blockchain_scripthash_get_balance = at<17>;
118+
using blockchain_scripthash_get_history = at<18>;
119+
using blockchain_scripthash_get_mempool = at<19>;
120+
using blockchain_scripthash_list_unspent = at<20>;
121+
using blockchain_scripthash_subscribe = at<21>;
122+
using blockchain_scripthash_unsubscribe = at<22>;
123+
124+
using blockchain_scriptpubkey_get_balance = at<23>;
125+
using blockchain_scriptpubkey_get_history = at<24>;
126+
using blockchain_scriptpubkey_get_mempool = at<25>;
127+
using blockchain_scriptpubkey_list_unspent = at<26>;
128+
using blockchain_scriptpubkey_subscribe = at<27>;
129+
using blockchain_scriptpubkey_unsubscribe = at<28>;
130+
131+
using blockchain_transaction_broadcast = at<29>;
132+
using blockchain_transaction_broadcast_package = at<30>;
133+
using blockchain_transaction_get = at<31>;
134+
using blockchain_transaction_get_merkle = at<32>;
135+
using blockchain_transaction_id_from_position = at<33>;
136+
137+
using server_add_peer = at<34>;
138+
using server_banner = at<35>;
139+
using server_donation_address = at<36>;
140+
using server_features = at<37>;
141+
using server_peers_subscribe = at<38>;
142+
using server_ping = at<39>;
143+
using server_version = at<40>;
144+
145+
using mempool_get_fee_histogram = at<41>;
146+
using mempool_get_info = at<42>;
125147
};
126148

127149
} // namespace interface

include/bitcoin/server/protocols/protocol_electrum.hpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,23 @@ class BCS_API protocol_electrum
8787
void handle_blockchain_relay_fee(const code& ec,
8888
rpc_interface::blockchain_relay_fee) NOEXCEPT;
8989

90-
/// Handlers (addresses).
90+
/// Handlers (outputs).
9191
void handle_blockchain_utxo_get_address(const code& ec,
9292
rpc_interface::blockchain_utxo_get_address,
9393
const std::string& tx_hash, double index) NOEXCEPT;
94+
void handle_blockchain_outpoint_get_status(const code& ec,
95+
rpc_interface::blockchain_outpoint_get_status,
96+
const std::string& tx_hash, double index,
97+
const std::string& spk_hint) NOEXCEPT;
98+
void handle_blockchain_outpoint_subscribe(const code& ec,
99+
rpc_interface::blockchain_outpoint_subscribe,
100+
const std::string& tx_hash, double index,
101+
const std::string& spk_hint) NOEXCEPT;
102+
void handle_blockchain_outpoint_unsubscribe(const code& ec,
103+
rpc_interface::blockchain_outpoint_unsubscribe,
104+
const std::string& tx_hash, double index) NOEXCEPT;
105+
106+
/// Handlers (addresses).
94107
void handle_blockchain_address_get_balance(const code& ec,
95108
rpc_interface::blockchain_address_get_balance,
96109
const std::string& address) NOEXCEPT;
@@ -127,6 +140,26 @@ class BCS_API protocol_electrum
127140
rpc_interface::blockchain_scripthash_unsubscribe,
128141
const std::string& scripthash) NOEXCEPT;
129142

143+
/// Handlers (scriptpubkey).
144+
void handle_blockchain_scriptpubkey_get_balance(const code& ec,
145+
rpc_interface::blockchain_scriptpubkey_get_balance,
146+
const std::string& scriptpubkey) NOEXCEPT;
147+
void handle_blockchain_scriptpubkey_get_history(const code& ec,
148+
rpc_interface::blockchain_scriptpubkey_get_history,
149+
const std::string& scriptpubkey) NOEXCEPT;
150+
void handle_blockchain_scriptpubkey_get_mempool(const code& ec,
151+
rpc_interface::blockchain_scriptpubkey_get_mempool,
152+
const std::string& scriptpubkey) NOEXCEPT;
153+
void handle_blockchain_scriptpubkey_list_unspent(const code& ec,
154+
rpc_interface::blockchain_scriptpubkey_list_unspent,
155+
const std::string& scriptpubkey) NOEXCEPT;
156+
void handle_blockchain_scriptpubkey_subscribe(const code& ec,
157+
rpc_interface::blockchain_scriptpubkey_subscribe,
158+
const std::string& scriptpubkey) NOEXCEPT;
159+
void handle_blockchain_scriptpubkey_unsubscribe(const code& ec,
160+
rpc_interface::blockchain_scriptpubkey_unsubscribe,
161+
const std::string& scriptpubkey) NOEXCEPT;
162+
130163
/// Handlers (transactions).
131164
void handle_blockchain_transaction_broadcast(const code& ec,
132165
rpc_interface::blockchain_transaction_broadcast,
@@ -202,7 +235,10 @@ class BCS_API protocol_electrum
202235

203236
void do_height(node::header_t link) NOEXCEPT;
204237
void do_header(node::header_t link) NOEXCEPT;
238+
void do_outpoint(node::header_t link) NOEXCEPT;
205239
void do_address(node::address_t link) NOEXCEPT;
240+
void do_scripthash(node::address_t link) NOEXCEPT;
241+
void do_scriptpubkey(node::address_t link) NOEXCEPT;
206242

207243
/// Utilities.
208244
/// -----------------------------------------------------------------------
@@ -251,8 +287,10 @@ class BCS_API protocol_electrum
251287
std::atomic_bool stopping_{};
252288
std::atomic_bool subscribed_height_{};
253289
std::atomic_bool subscribed_header_{};
290+
std::atomic_bool subscribed_outpoint_{};
254291
std::atomic_bool subscribed_address_{};
255292
std::atomic_bool subscribed_scripthash_{};
293+
std::atomic_bool subscribed_scriptpubkey_{};
256294

257295
// This is mostly thread safe, and used in a thread safe manner.
258296
const channel_t::ptr channel_;

src/protocols/electrum/protocol_electrum.cpp

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,13 @@ void protocol_electrum::start() NOEXCEPT
6464
SUBSCRIBE_RPC(handle_blockchain_estimate_fee, _1, _2, _3, _4);
6565
SUBSCRIBE_RPC(handle_blockchain_relay_fee, _1, _2);
6666

67-
// Address methods.
67+
// Output methods.
6868
SUBSCRIBE_RPC(handle_blockchain_utxo_get_address, _1, _2, _3, _4);
69+
SUBSCRIBE_RPC(handle_blockchain_outpoint_get_status, _1, _2, _3, _4, _5);
70+
SUBSCRIBE_RPC(handle_blockchain_outpoint_subscribe, _1, _2, _3, _4, _5);
71+
SUBSCRIBE_RPC(handle_blockchain_outpoint_unsubscribe, _1, _2, _3, _4);
72+
73+
// Address methods.
6974
SUBSCRIBE_RPC(handle_blockchain_address_get_balance, _1, _2, _3);
7075
SUBSCRIBE_RPC(handle_blockchain_address_get_history, _1, _2, _3);
7176
SUBSCRIBE_RPC(handle_blockchain_address_get_mempool, _1, _2, _3);
@@ -80,6 +85,14 @@ void protocol_electrum::start() NOEXCEPT
8085
SUBSCRIBE_RPC(handle_blockchain_scripthash_subscribe, _1, _2, _3);
8186
SUBSCRIBE_RPC(handle_blockchain_scripthash_unsubscribe, _1, _2, _3);
8287

88+
// Scriptpubkey methods.
89+
SUBSCRIBE_RPC(handle_blockchain_scriptpubkey_get_balance, _1, _2, _3);
90+
SUBSCRIBE_RPC(handle_blockchain_scriptpubkey_get_history, _1, _2, _3);
91+
SUBSCRIBE_RPC(handle_blockchain_scriptpubkey_get_mempool, _1, _2, _3);
92+
SUBSCRIBE_RPC(handle_blockchain_scriptpubkey_list_unspent, _1, _2, _3);
93+
SUBSCRIBE_RPC(handle_blockchain_scriptpubkey_subscribe, _1, _2, _3);
94+
SUBSCRIBE_RPC(handle_blockchain_scriptpubkey_unsubscribe, _1, _2, _3);
95+
8396
// Transaction methods.
8497
SUBSCRIBE_RPC(handle_blockchain_transaction_broadcast, _1, _2, _3);
8598
SUBSCRIBE_RPC(handle_blockchain_transaction_broadcast_package, _1, _2, _3, _4);
@@ -144,11 +157,29 @@ bool protocol_electrum::handle_event(const code&, node::chase event_,
144157
case node::chase::spent:
145158
case node::chase::received:
146159
{
160+
if (subscribed_outpoint_.load(relaxed))
161+
{
162+
BC_ASSERT(std::holds_alternative<node::address_t>(value));
163+
POST(do_outpoint, std::get<node::address_t>(value));
164+
}
165+
147166
if (subscribed_address_.load(relaxed))
148167
{
149168
BC_ASSERT(std::holds_alternative<node::address_t>(value));
150169
POST(do_address, std::get<node::address_t>(value));
151170
}
171+
172+
if (subscribed_scripthash_.load(relaxed))
173+
{
174+
BC_ASSERT(std::holds_alternative<node::address_t>(value));
175+
POST(do_scripthash, std::get<node::address_t>(value));
176+
}
177+
178+
if (subscribed_scriptpubkey_.load(relaxed))
179+
{
180+
BC_ASSERT(std::holds_alternative<node::address_t>(value));
181+
POST(do_scriptpubkey, std::get<node::address_t>(value));
182+
}
152183
}
153184
default:
154185
{
@@ -205,6 +236,19 @@ void protocol_electrum::do_header(node::header_t link) NOEXCEPT
205236
}, 64, BIND(complete, _1));
206237
}
207238

239+
// Notifier for blockchain_outpoint_subscribe events.
240+
void protocol_electrum::do_outpoint(node::address_t) NOEXCEPT
241+
{
242+
chain::point point{};
243+
244+
// TODO: compute and return outpont status from a store query.
245+
send_notification("blockchain.outpoint.subscribe", array_t
246+
{
247+
array_t{ encode_hash(point.hash()), point.index() },
248+
object_t{}
249+
}, 128, BIND(handle_send, _1));
250+
}
251+
208252
// This struct is small and stack allocated (208 bytes).
209253
// Writer holds stream ref to status and midstate via accumulator.
210254
// Writer flush rewrites status via stream and resets accumulator.
@@ -218,7 +262,6 @@ struct midstate
218262
};
219263

220264
// Notifier for blockchain_address_subscribe events.
221-
// Notifier for blockchain_scripthash_unsubscribe events.
222265
void protocol_electrum::do_address(node::address_t ) NOEXCEPT
223266
{
224267
std::string status_hash{};
@@ -229,13 +272,42 @@ void protocol_electrum::do_address(node::address_t ) NOEXCEPT
229272

230273
// EXAMPLE
231274
// script_hash is a payment address for address.
232-
////send_notification("blockchain.address.subscribe", array_t
275+
send_notification("blockchain.address.subscribe", array_t
276+
{
277+
script_hash,
278+
status_hash
279+
}, 128, BIND(handle_send, _1));
280+
}
281+
282+
// Notifier for blockchain_scripthash_subscribe events.
283+
void protocol_electrum::do_scripthash(node::address_t) NOEXCEPT
284+
{
285+
std::string status_hash{};
286+
std::string script_hash{};
287+
288+
// EXAMPLE
289+
// script_hash is a payment address for address.
233290
send_notification("blockchain.scripthash.subscribe", array_t
234291
{
235292
script_hash,
236293
status_hash
237294
}, 128, BIND(handle_send, _1));
238295
}
239296

297+
// Notifier for blockchain_scriptpubkey_subscribe events.
298+
void protocol_electrum::do_scriptpubkey(node::address_t) NOEXCEPT
299+
{
300+
std::string status_hash{};
301+
std::string script_hash{};
302+
303+
// EXAMPLE
304+
// script_hash is a payment address for address.
305+
send_notification("blockchain.scriptpubkey.subscribe", array_t
306+
{
307+
script_hash,
308+
status_hash
309+
}, 128, BIND(handle_send, _1));
310+
}
311+
240312
} // namespace server
241313
} // namespace libbitcoin

0 commit comments

Comments
 (0)