Skip to content

Commit a3aa6b7

Browse files
authored
Merge pull request #692 from evoskuil/master
Implement basic protocol_rpc senders.
2 parents eccd78d + bdd8924 commit a3aa6b7

File tree

4 files changed

+76
-13
lines changed

4 files changed

+76
-13
lines changed

include/bitcoin/network/channels/channel_rpc.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class channel_rpc
4040

4141
/// Subscribe to request from client (requires strand).
4242
/// Event handler is always invoked on the channel strand.
43-
template <class Void, class Handler>
43+
template <class Unused, class Handler>
4444
inline void subscribe(Handler&& handler) NOEXCEPT
4545
{
4646
BC_ASSERT(stranded());

include/bitcoin/network/messages/http_body.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ using string_value = http::string_body::value_type;
8181
using json_value = http::json_body::value_type;
8282
using body_value = std::variant
8383
<
84-
empty_value,
85-
data_value,
86-
file_value,
87-
span_value,
88-
buffer_value,
89-
string_value,
90-
json_value,
91-
rpc::request,
92-
rpc::response
84+
empty_value, // 1 byte
85+
data_value, // 40 bytes
86+
file_value, // 32 bytes
87+
span_value, // 16 bytes
88+
buffer_value, // 24 bytes
89+
string_value, // 40 bytes
90+
json_value, // 48 bytes
91+
rpc::request, // 248 bytes!
92+
rpc::response // 360 bytes!
9393
>;
9494

9595
/// body template for all known message types.

include/bitcoin/network/protocols/protocol.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,12 @@ class BCT_API protocol
211211

212212
#define DECLARE_SEND() \
213213
template <class Derived, class Message, typename Method, typename... Args> \
214-
void send(Message&& message, Method&& method, Args&&... args) NOEXCEPT \
214+
inline void send(Message&& message, Method&& method, Args&&... args) NOEXCEPT \
215215
{ channel_->send(std::forward<Message>(message), BIND_SHARED(method, args)); }
216216

217217
#define DECLARE_SUBSCRIBE_CHANNEL() \
218218
template <class Derived, class Message, typename Method, typename... Args> \
219-
void subscribe_channel(Method&& method, Args&&... args) NOEXCEPT \
219+
inline void subscribe_channel(Method&& method, Args&&... args) NOEXCEPT \
220220
{ channel_->template subscribe<Message>(BIND_SHARED(method, args)); }
221221

222222
#define SEND(message, method, ...) \

include/bitcoin/network/protocols/protocol_rpc.hpp

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define LIBBITCOIN_NETWORK_PROTOCOL_RPC_HPP
2121

2222
#include <memory>
23+
#include <utility>
2324
#include <bitcoin/network/channels/channels.hpp>
2425
#include <bitcoin/network/define.hpp>
2526
#include <bitcoin/network/protocols/protocol.hpp>
@@ -33,6 +34,7 @@ class protocol_rpc
3334
{
3435
public:
3536
typedef std::shared_ptr<protocol> ptr;
37+
using protocol_t = protocol_rpc<Interface>;
3638
using channel_t = channel_rpc<Interface>;
3739
using options_t = channel_t::options_t;
3840

@@ -44,9 +46,70 @@ class protocol_rpc
4446
{
4547
}
4648

47-
DECLARE_SEND()
4849
DECLARE_SUBSCRIBE_CHANNEL()
4950

51+
template <class Derived, typename Method, typename... Args>
52+
inline void send(network::rpc::response_t&& message, size_t size_hint,
53+
Method&& method, Args&&... args) NOEXCEPT
54+
{
55+
channel_->send(std::move(message), size_hint,
56+
std::bind(std::forward<Method>(method),
57+
shared_from_base<Derived>(), std::forward<Args>(args)...));
58+
}
59+
60+
// TODO: capture and correlate version/id.
61+
inline void send_result(network::rpc::value_t&& value,
62+
size_t size_hint) NOEXCEPT
63+
{
64+
using namespace network::rpc;
65+
using namespace std::placeholders;
66+
send<protocol_t>(
67+
{
68+
.jsonrpc = version::v2,
69+
.id = 42,
70+
////.error = {},
71+
.result = std::move(value)
72+
},
73+
size_hint, &protocol_t::handle_complete, _1, error::success);
74+
}
75+
76+
// TODO: capture and correlate version/id.
77+
inline void send_error(const code& reason) NOEXCEPT
78+
{
79+
using namespace network::rpc;
80+
using namespace std::placeholders;
81+
const auto size_hint = two * reason.message().size();
82+
send<protocol_t>(
83+
{
84+
.jsonrpc = version::v2,
85+
.id = 42,
86+
.error = result_t
87+
{
88+
.code = reason.value(),
89+
.message = reason.message()
90+
}
91+
////.result = {}
92+
},
93+
size_hint, &protocol_t::handle_complete, _1, reason);
94+
}
95+
96+
inline void handle_complete(const code& ec, const code& reason) NOEXCEPT
97+
{
98+
BC_ASSERT(stranded());
99+
100+
if (stopped(ec))
101+
return;
102+
103+
if (reason)
104+
{
105+
stop(reason);
106+
return;
107+
}
108+
109+
// Continue read loop.
110+
channel_->receive();
111+
}
112+
50113
private:
51114
// This is mostly thread safe, and used in a thread safe manner.
52115
// pause/resume/paused/attach not invoked, setters limited to handshake.

0 commit comments

Comments
 (0)