RPC: option to render block as JSON (#1740)
* Option to render block as JSON in create_block * Better local var name * Add ptree serialization to all block types, support flag in block_info * Add flag to other RPC's doing stringified blocks * Add test for the json_block option
This commit is contained in:
parent
c926f0a6e0
commit
62914cc9e8
4 changed files with 159 additions and 33 deletions
|
@ -3411,6 +3411,36 @@ TEST (rpc, account_info)
|
|||
ASSERT_EQ (nano::test_genesis_key.pub.to_account (), representative2);
|
||||
}
|
||||
|
||||
TEST (rpc, json_block)
|
||||
{
|
||||
nano::system system (24000, 1);
|
||||
nano::keypair key;
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
system.wallet (0)->insert_adhoc (key.prv);
|
||||
auto & node1 (*system.nodes[0]);
|
||||
auto latest (system.nodes[0]->latest (nano::test_genesis_key.pub));
|
||||
nano::send_block send (latest, key.pub, 100, nano::test_genesis_key.prv, nano::test_genesis_key.pub, node1.work_generate_blocking (latest));
|
||||
system.nodes[0]->process (send);
|
||||
nano::rpc rpc (system.io_ctx, *system.nodes[0], nano::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "block_info");
|
||||
request.put ("json_block", "true");
|
||||
request.put ("hash", send.hash ().to_string ());
|
||||
test_response response (request, rpc, system.io_ctx);
|
||||
system.deadline_set (5s);
|
||||
while (response.status == 0)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_EQ (200, response.status);
|
||||
|
||||
// Make sure contents contains a valid JSON subtree instread of stringified json
|
||||
bool json_error{ false };
|
||||
nano::send_block send_from_json (json_error, response.json.get_child ("contents"));
|
||||
ASSERT_FALSE (json_error);
|
||||
}
|
||||
|
||||
TEST (rpc, blocks_info)
|
||||
{
|
||||
nano::system system (24000, 1);
|
||||
|
|
|
@ -240,6 +240,14 @@ bool nano::send_block::deserialize (nano::stream & stream_a)
|
|||
void nano::send_block::serialize_json (std::string & string_a) const
|
||||
{
|
||||
boost::property_tree::ptree tree;
|
||||
serialize_json (tree);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
void nano::send_block::serialize_json (boost::property_tree::ptree & tree) const
|
||||
{
|
||||
tree.put ("type", "send");
|
||||
std::string previous;
|
||||
hashables.previous.encode_hex (previous);
|
||||
|
@ -252,9 +260,6 @@ void nano::send_block::serialize_json (std::string & string_a) const
|
|||
signature.encode_hex (signature_l);
|
||||
tree.put ("work", nano::to_string_hex (work));
|
||||
tree.put ("signature", signature_l);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
bool nano::send_block::deserialize_json (boost::property_tree::ptree const & tree_a)
|
||||
|
@ -555,6 +560,14 @@ bool nano::open_block::deserialize (nano::stream & stream_a)
|
|||
void nano::open_block::serialize_json (std::string & string_a) const
|
||||
{
|
||||
boost::property_tree::ptree tree;
|
||||
serialize_json (tree);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
void nano::open_block::serialize_json (boost::property_tree::ptree & tree) const
|
||||
{
|
||||
tree.put ("type", "open");
|
||||
tree.put ("source", hashables.source.to_string ());
|
||||
tree.put ("representative", representative ().to_account ());
|
||||
|
@ -563,9 +576,6 @@ void nano::open_block::serialize_json (std::string & string_a) const
|
|||
signature.encode_hex (signature_l);
|
||||
tree.put ("work", nano::to_string_hex (work));
|
||||
tree.put ("signature", signature_l);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
bool nano::open_block::deserialize_json (boost::property_tree::ptree const & tree_a)
|
||||
|
@ -792,6 +802,14 @@ bool nano::change_block::deserialize (nano::stream & stream_a)
|
|||
void nano::change_block::serialize_json (std::string & string_a) const
|
||||
{
|
||||
boost::property_tree::ptree tree;
|
||||
serialize_json (tree);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
void nano::change_block::serialize_json (boost::property_tree::ptree & tree) const
|
||||
{
|
||||
tree.put ("type", "change");
|
||||
tree.put ("previous", hashables.previous.to_string ());
|
||||
tree.put ("representative", representative ().to_account ());
|
||||
|
@ -799,9 +817,6 @@ void nano::change_block::serialize_json (std::string & string_a) const
|
|||
std::string signature_l;
|
||||
signature.encode_hex (signature_l);
|
||||
tree.put ("signature", signature_l);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
bool nano::change_block::deserialize_json (boost::property_tree::ptree const & tree_a)
|
||||
|
@ -1075,6 +1090,14 @@ bool nano::state_block::deserialize (nano::stream & stream_a)
|
|||
void nano::state_block::serialize_json (std::string & string_a) const
|
||||
{
|
||||
boost::property_tree::ptree tree;
|
||||
serialize_json (tree);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
void nano::state_block::serialize_json (boost::property_tree::ptree & tree) const
|
||||
{
|
||||
tree.put ("type", "state");
|
||||
tree.put ("account", hashables.account.to_account ());
|
||||
tree.put ("previous", hashables.previous.to_string ());
|
||||
|
@ -1086,9 +1109,6 @@ void nano::state_block::serialize_json (std::string & string_a) const
|
|||
signature.encode_hex (signature_l);
|
||||
tree.put ("signature", signature_l);
|
||||
tree.put ("work", nano::to_string_hex (work));
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
bool nano::state_block::deserialize_json (boost::property_tree::ptree const & tree_a)
|
||||
|
@ -1367,6 +1387,14 @@ bool nano::receive_block::deserialize (nano::stream & stream_a)
|
|||
void nano::receive_block::serialize_json (std::string & string_a) const
|
||||
{
|
||||
boost::property_tree::ptree tree;
|
||||
serialize_json (tree);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
void nano::receive_block::serialize_json (boost::property_tree::ptree & tree) const
|
||||
{
|
||||
tree.put ("type", "receive");
|
||||
std::string previous;
|
||||
hashables.previous.encode_hex (previous);
|
||||
|
@ -1378,9 +1406,6 @@ void nano::receive_block::serialize_json (std::string & string_a) const
|
|||
signature.encode_hex (signature_l);
|
||||
tree.put ("work", nano::to_string_hex (work));
|
||||
tree.put ("signature", signature_l);
|
||||
std::stringstream ostream;
|
||||
boost::property_tree::write_json (ostream, tree);
|
||||
string_a = ostream.str ();
|
||||
}
|
||||
|
||||
bool nano::receive_block::deserialize_json (boost::property_tree::ptree const & tree_a)
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
virtual nano::account representative () const;
|
||||
virtual void serialize (nano::stream &) const = 0;
|
||||
virtual void serialize_json (std::string &) const = 0;
|
||||
virtual void serialize_json (boost::property_tree::ptree &) const = 0;
|
||||
virtual void visit (nano::block_visitor &) const = 0;
|
||||
virtual bool operator== (nano::block const &) const = 0;
|
||||
virtual nano::block_type type () const = 0;
|
||||
|
@ -115,6 +116,7 @@ public:
|
|||
void serialize (nano::stream &) const override;
|
||||
bool deserialize (nano::stream &);
|
||||
void serialize_json (std::string &) const override;
|
||||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
nano::block_type type () const override;
|
||||
|
@ -158,6 +160,7 @@ public:
|
|||
void serialize (nano::stream &) const override;
|
||||
bool deserialize (nano::stream &);
|
||||
void serialize_json (std::string &) const override;
|
||||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
nano::block_type type () const override;
|
||||
|
@ -205,6 +208,7 @@ public:
|
|||
void serialize (nano::stream &) const override;
|
||||
bool deserialize (nano::stream &);
|
||||
void serialize_json (std::string &) const override;
|
||||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
nano::block_type type () const override;
|
||||
|
@ -248,6 +252,7 @@ public:
|
|||
void serialize (nano::stream &) const override;
|
||||
bool deserialize (nano::stream &);
|
||||
void serialize_json (std::string &) const override;
|
||||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
nano::block_type type () const override;
|
||||
|
@ -306,6 +311,7 @@ public:
|
|||
void serialize (nano::stream &) const override;
|
||||
bool deserialize (nano::stream &);
|
||||
void serialize_json (std::string &) const override;
|
||||
void serialize_json (boost::property_tree::ptree &) const override;
|
||||
bool deserialize_json (boost::property_tree::ptree const &);
|
||||
void visit (nano::block_visitor &) const override;
|
||||
nano::block_type type () const override;
|
||||
|
|
|
@ -820,9 +820,20 @@ void nano::rpc_handler::block_info ()
|
|||
response_l.put ("balance", balance.convert_to<std::string> ());
|
||||
response_l.put ("height", std::to_string (sideband.height));
|
||||
response_l.put ("local_timestamp", std::to_string (sideband.timestamp));
|
||||
std::string contents;
|
||||
block->serialize_json (contents);
|
||||
response_l.put ("contents", contents);
|
||||
|
||||
bool json_block_l = request.get<bool> ("json_block", false);
|
||||
if (json_block_l)
|
||||
{
|
||||
boost::property_tree::ptree block_node_l;
|
||||
block->serialize_json (block_node_l);
|
||||
response_l.add_child ("contents", block_node_l);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string contents;
|
||||
block->serialize_json (contents);
|
||||
response_l.put ("contents", contents);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -891,6 +902,8 @@ void nano::rpc_handler::blocks_info ()
|
|||
{
|
||||
const bool pending = request.get<bool> ("pending", false);
|
||||
const bool source = request.get<bool> ("source", false);
|
||||
const bool json_block_l = request.get<bool> ("json_block", false);
|
||||
|
||||
std::vector<std::string> hashes;
|
||||
boost::property_tree::ptree blocks;
|
||||
auto transaction (node.store.tx_begin_read ());
|
||||
|
@ -915,9 +928,20 @@ void nano::rpc_handler::blocks_info ()
|
|||
entry.put ("balance", balance.convert_to<std::string> ());
|
||||
entry.put ("height", std::to_string (sideband.height));
|
||||
entry.put ("local_timestamp", std::to_string (sideband.timestamp));
|
||||
std::string contents;
|
||||
block->serialize_json (contents);
|
||||
entry.put ("contents", contents);
|
||||
|
||||
if (json_block_l)
|
||||
{
|
||||
boost::property_tree::ptree block_node_l;
|
||||
block->serialize_json (block_node_l);
|
||||
entry.add_child ("contents", block_node_l);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string contents;
|
||||
block->serialize_json (contents);
|
||||
entry.put ("contents", contents);
|
||||
}
|
||||
|
||||
if (pending)
|
||||
{
|
||||
bool exists (false);
|
||||
|
@ -1164,9 +1188,19 @@ void nano::rpc_handler::block_create ()
|
|||
}
|
||||
nano::state_block state (pub, previous, representative, balance, link, prv, pub, work);
|
||||
response_l.put ("hash", state.hash ().to_string ());
|
||||
std::string contents;
|
||||
state.serialize_json (contents);
|
||||
response_l.put ("block", contents);
|
||||
bool json_block_l = request.get<bool> ("json_block", false);
|
||||
if (json_block_l)
|
||||
{
|
||||
boost::property_tree::ptree block_node_l;
|
||||
state.serialize_json (block_node_l);
|
||||
response_l.add_child ("block", block_node_l);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string contents;
|
||||
state.serialize_json (contents);
|
||||
response_l.put ("block", contents);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1477,6 +1511,7 @@ void nano::rpc_handler::confirmation_info ()
|
|||
{
|
||||
const bool representatives = request.get<bool> ("representatives", false);
|
||||
const bool contents = request.get<bool> ("contents", true);
|
||||
const bool json_block_l = request.get<bool> ("json_block", false);
|
||||
std::string root_text (request.get<std::string> ("root"));
|
||||
nano::uint512_union root;
|
||||
if (!root.decode_hex (root_text))
|
||||
|
@ -1500,9 +1535,18 @@ void nano::rpc_handler::confirmation_info ()
|
|||
total += tally;
|
||||
if (contents)
|
||||
{
|
||||
std::string contents;
|
||||
i->second->serialize_json (contents);
|
||||
entry.put ("contents", contents);
|
||||
if (json_block_l)
|
||||
{
|
||||
boost::property_tree::ptree block_node_l;
|
||||
i->second->serialize_json (block_node_l);
|
||||
entry.add_child ("contents", block_node_l);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string contents;
|
||||
i->second->serialize_json (contents);
|
||||
entry.put ("contents", contents);
|
||||
}
|
||||
}
|
||||
if (representatives)
|
||||
{
|
||||
|
@ -3185,6 +3229,7 @@ void nano::rpc_handler::unchecked_clear ()
|
|||
|
||||
void nano::rpc_handler::unchecked_get ()
|
||||
{
|
||||
const bool json_block_l = request.get<bool> ("json_block", false);
|
||||
auto hash (hash_impl ());
|
||||
if (!ec)
|
||||
{
|
||||
|
@ -3196,9 +3241,19 @@ void nano::rpc_handler::unchecked_get ()
|
|||
{
|
||||
nano::unchecked_info info (i->second);
|
||||
response_l.put ("modified_timestamp", std::to_string (info.modified));
|
||||
std::string contents;
|
||||
info.block->serialize_json (contents);
|
||||
response_l.put ("contents", contents);
|
||||
|
||||
if (json_block_l)
|
||||
{
|
||||
boost::property_tree::ptree block_node_l;
|
||||
info.block->serialize_json (block_node_l);
|
||||
response_l.add_child ("contents", block_node_l);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string contents;
|
||||
info.block->serialize_json (contents);
|
||||
response_l.put ("contents", contents);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3212,6 +3267,7 @@ void nano::rpc_handler::unchecked_get ()
|
|||
|
||||
void nano::rpc_handler::unchecked_keys ()
|
||||
{
|
||||
const bool json_block_l = request.get<bool> ("json_block", false);
|
||||
auto count (count_optional_impl ());
|
||||
nano::uint256_union key (0);
|
||||
boost::optional<std::string> hash_text (request.get_optional<std::string> ("key"));
|
||||
|
@ -3230,12 +3286,21 @@ void nano::rpc_handler::unchecked_keys ()
|
|||
{
|
||||
boost::property_tree::ptree entry;
|
||||
nano::unchecked_info info (i->second);
|
||||
std::string contents;
|
||||
info.block->serialize_json (contents);
|
||||
entry.put ("key", nano::block_hash (i->first.key ()).to_string ());
|
||||
entry.put ("hash", info.block->hash ().to_string ());
|
||||
entry.put ("modified_timestamp", std::to_string (info.modified));
|
||||
entry.put ("contents", contents);
|
||||
if (json_block_l)
|
||||
{
|
||||
boost::property_tree::ptree block_node_l;
|
||||
info.block->serialize_json (block_node_l);
|
||||
entry.add_child ("contents", block_node_l);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string contents;
|
||||
info.block->serialize_json (contents);
|
||||
entry.put ("contents", contents);
|
||||
}
|
||||
unchecked.push_back (std::make_pair ("", entry));
|
||||
}
|
||||
response_l.add_child ("unchecked", unchecked);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue