Skip to content

Commit 79c33b6

Browse files
Merge pull request #199 from thecodefactory/rpc
Begin adding JSON-RPC formatting support.
2 parents 4b0c6c9 + d510686 commit 79c33b6

File tree

5 files changed

+205
-54
lines changed

5 files changed

+205
-54
lines changed

include/bitcoin/protocol/web/json_string.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ namespace http {
3535
//-----------------------------------------------------------------------------
3636

3737
BCP_API std::string to_json(const boost::property_tree::ptree& tree);
38+
BCP_API std::string to_json(const boost::property_tree::ptree& tree,
39+
uint32_t id);
3840
BCP_API std::string to_json(uint64_t height, uint32_t id);
41+
BCP_API std::string to_json(const system::hash_digest& hash, uint32_t id);
3942
BCP_API std::string to_json(const system::code& code, uint32_t id);
4043
BCP_API std::string to_json(const system::chain::header& header, uint32_t id);
4144
BCP_API std::string to_json(const system::chain::block& block, uint32_t id);
@@ -44,6 +47,27 @@ BCP_API std::string to_json(const system::chain::block& block, uint32_t height,
4447
BCP_API std::string to_json(const system::chain::transaction& transaction,
4548
uint32_t id);
4649

50+
// Object to JSON rpc converters.
51+
//-----------------------------------------------------------------------------
52+
53+
// The rpc distinction is for formatting the json to conform to
54+
// libbitcoin json, or rpc json.
55+
namespace rpc {
56+
57+
BCP_API std::string to_json(const boost::property_tree::ptree& tree,
58+
uint32_t id);
59+
BCP_API std::string to_json(uint64_t height, uint32_t id);
60+
BCP_API std::string to_json(const system::hash_digest& hash, uint32_t id);
61+
BCP_API std::string to_json(const system::code& code, uint32_t id);
62+
BCP_API std::string to_json(const system::chain::header& header, uint32_t id);
63+
BCP_API std::string to_json(const system::chain::block& block, uint32_t id);
64+
BCP_API std::string to_json(const system::chain::block& block, uint32_t height,
65+
uint32_t id);
66+
BCP_API std::string to_json(const system::chain::transaction& transaction,
67+
uint32_t id);
68+
69+
} // namespace rpc
70+
4771
} // namespace http
4872
} // namespace protocol
4973
} // namespace libbitcoin

include/bitcoin/protocol/web/socket.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class BCP_API socket
6363
// converting the result back to JSON for web clients.
6464
struct handlers
6565
{
66-
typedef std::function<void(bc::protocol::zmq::message&,
66+
typedef std::function<bool(bc::protocol::zmq::message&,
6767
const std::string&, const std::string&, uint32_t)> encode_handler;
6868
typedef std::function<void(const system::data_chunk&, uint32_t,
6969
connection_ptr)> decode_handler;
@@ -135,8 +135,9 @@ class BCP_API socket
135135
const std::string security_;
136136
const bc::protocol::settings& settings_;
137137

138-
// handlers_ is effectively const.
138+
// Both handlers_ and rpc_handlers_ are effectively const.
139139
handler_map handlers_;
140+
handler_map rpc_handlers_;
140141

141142
// For query socket, service() is used to retrieve the zmq socket
142143
// connected to the query_socket service. This socket operates on

src/web/json_string.cpp

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,60 @@ std::string to_json(const ptree& tree, uint32_t id)
5757

5858
std::string to_json(uint64_t height, uint32_t id)
5959
{
60-
ptree tree;
61-
tree.put("result", height);
60+
return to_json(property_tree(height, id));
61+
}
62+
63+
std::string to_json(const code& code, uint32_t id)
64+
{
65+
return to_json(property_tree(code, id));
66+
}
67+
68+
std::string to_json(const hash_digest& hash, uint32_t id)
69+
{
70+
auto tree = property_tree(hash);
6271
tree.put("id", id);
6372
return to_json(tree);
73+
}
6474

65-
// TODO: The bc::property_tree call works fine, but the format is
66-
// different than expected for json_rpc so eventually we need to
67-
// separate out property_tree and json_rpc::property_tree, or
68-
// something along the lines to make this a clear distinction.
69-
//// return to_json(property_tree(height, id));
75+
std::string to_json(const chain::header& header, uint32_t id)
76+
{
77+
return to_json(property_tree(config::header(header)), id);
78+
}
79+
80+
std::string to_json(const chain::block& block, uint32_t id)
81+
{
82+
return to_json(property_tree(block, true), id);
83+
}
84+
85+
std::string to_json(const chain::block& block, uint32_t, uint32_t id)
86+
{
87+
return to_json(property_tree(config::header(block.header())), id);
88+
}
89+
90+
std::string to_json(const chain::transaction& transaction, uint32_t id)
91+
{
92+
return to_json(property_tree(config::transaction(transaction), true), id);
93+
}
94+
95+
// Object to JSON rpc converters.
96+
//-----------------------------------------------------------------------------
97+
98+
namespace rpc {
99+
100+
std::string to_json(const ptree& tree, uint32_t id)
101+
{
102+
ptree result_tree;
103+
result_tree.add_child("result", tree);
104+
result_tree.put("id", id);
105+
return http::to_json(result_tree);
106+
}
107+
108+
std::string to_json(uint64_t height, uint32_t id)
109+
{
110+
ptree tree;
111+
tree.put("result", height);
112+
tree.put("id", id);
113+
return http::to_json(tree);
70114
}
71115

72116
std::string to_json(const code& code, uint32_t id)
@@ -77,13 +121,36 @@ std::string to_json(const code& code, uint32_t id)
77121
error_tree.put("message", code.message());
78122
tree.add_child("error", error_tree);
79123
tree.put("id", id);
80-
return to_json(tree);
81-
//// return to_json(property_tree(code, id));
124+
return http::to_json(tree);
125+
}
126+
127+
std::string to_json(const hash_digest& hash, uint32_t id)
128+
{
129+
ptree tree;
130+
tree.put("result", encode_hash(hash));
131+
tree.put("id", id);
132+
return http::to_json(tree);
82133
}
83134

84135
std::string to_json(const chain::header& header, uint32_t id)
85136
{
86-
return to_json(property_tree(config::header(header)), id);
137+
auto hex = [](uint32_t value)
138+
{
139+
std::stringstream hex_value;
140+
hex_value << std::setfill('0') << std::setw(sizeof(uint32_t) * 2);
141+
hex_value << std::hex << value;
142+
return hex_value.str();
143+
};
144+
145+
ptree tree;
146+
tree.put("hash", encode_hash(header.hash()));
147+
tree.put("version", header.version());
148+
tree.put("versionHex", hex(header.version()));
149+
tree.put("merkleroot", encode_hash(header.merkle_root()));
150+
tree.put("time", header.timestamp());
151+
tree.put("nonce", header.nonce());
152+
tree.put("bits", hex(header.bits()));
153+
return to_json(tree, id);
87154
}
88155

89156
std::string to_json(const chain::block& block, uint32_t id)
@@ -93,14 +160,17 @@ std::string to_json(const chain::block& block, uint32_t id)
93160

94161
std::string to_json(const chain::block& block, uint32_t, uint32_t id)
95162
{
96-
return to_json(property_tree(config::header(block.header())), id);
163+
return to_json(block.header(), id);
97164
}
98165

99166
std::string to_json(const chain::transaction& transaction, uint32_t id)
100167
{
101168
return to_json(property_tree(config::transaction(transaction), true), id);
102169
}
103170

171+
} // namespace rpc
172+
173+
104174
} // namespace http
105175
} // namespace protocol
106176
} // namespace libbitcoin

src/web/manager.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ bool manager::bind(const config::endpoint& address, const bind_options& options)
140140

141141
if (!options.ssl_ca_certificate.empty())
142142
{
143-
// Specified and not found CA cert is a failure condition.
143+
// Specified and not found CA certificate is a failure condition.
144144
if (!exists(options.ssl_ca_certificate))
145145
{
146146
LOG_ERROR(LOG_PROTOCOL_HTTP)
@@ -878,9 +878,9 @@ bool manager::handle_websocket(connection_ptr connection)
878878
const auto header_length = frame.header_length();
879879

880880
LOG_VERBOSE(LOG_PROTOCOL_HTTP)
881-
<< "Websocket data_frame flags: " << flags
882-
<< ", final_fragment: " << (final ? "true" : "false")
883-
<< ", read length: " << read_length;
881+
<< "Websocket data_frame flags: 0x" << std::hex
882+
<< static_cast<uint32_t>(flags) << std::dec << ", final_fragment: "
883+
<< (final ? "true" : "false") << ", read length: " << read_length;
884884

885885
// If full frame payload isn't buffered, initiate state to track transfer.
886886
if (data_length > read_length && !transfer.in_progress)
@@ -1108,8 +1108,9 @@ bool manager::upgrade_connection(connection_ptr connection,
11081108
return false;
11091109
}
11101110

1111-
// Verify if origin is acceptable (contains either localhost, hostname,
1112-
// or ip address of current server)
1111+
// Verify if origin is acceptable (i.e. contains any of the
1112+
// configured acceptable origins, e.g. localhost, hostname, or ip
1113+
// address of current server)
11131114
if (!validate_origin(request.header("origin")))
11141115
{
11151116
LOG_ERROR(LOG_PROTOCOL_HTTP)
@@ -1196,7 +1197,7 @@ bool manager::initialize_ssl(connection_ptr connection, bool listener)
11961197
key_ = certificate_;
11971198

11981199
LOG_VERBOSE(LOG_PROTOCOL_HTTP)
1199-
<< "Using cert " << certificate_ << " and key " << key_;
1200+
<< "Using certificate " << certificate_ << " and key " << key_;
12001201

12011202
mbedtls_pk_init(&context.key);
12021203
mbedtls_x509_crt_init(&context.certificate);

0 commit comments

Comments
 (0)