Add optional "offset" & "reverse" parameters for RPC chain (#1622)
This commit is contained in:
parent
2c22b21025
commit
510a91ef30
3 changed files with 94 additions and 36 deletions
|
@ -925,6 +925,39 @@ TEST (rpc, chain_limit)
|
|||
ASSERT_EQ (block->hash (), blocks[0]);
|
||||
}
|
||||
|
||||
TEST (rpc, chain_offset)
|
||||
{
|
||||
nano::system system (24000, 1);
|
||||
system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv);
|
||||
nano::keypair key;
|
||||
auto genesis (system.nodes[0]->latest (nano::test_genesis_key.pub));
|
||||
ASSERT_FALSE (genesis.is_zero ());
|
||||
auto block (system.wallet (0)->send_action (nano::test_genesis_key.pub, key.pub, 1));
|
||||
ASSERT_NE (nullptr, block);
|
||||
nano::rpc rpc (system.io_ctx, *system.nodes[0], nano::rpc_config (true));
|
||||
rpc.start ();
|
||||
boost::property_tree::ptree request;
|
||||
request.put ("action", "chain");
|
||||
request.put ("block", block->hash ().to_string ());
|
||||
request.put ("count", std::to_string (std::numeric_limits<uint64_t>::max ()));
|
||||
request.put ("offset", 1);
|
||||
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);
|
||||
auto & blocks_node (response.json.get_child ("blocks"));
|
||||
std::vector<nano::block_hash> blocks;
|
||||
for (auto i (blocks_node.begin ()), n (blocks_node.end ()); i != n; ++i)
|
||||
{
|
||||
blocks.push_back (nano::block_hash (i->second.get<std::string> ("")));
|
||||
}
|
||||
ASSERT_EQ (1, blocks.size ());
|
||||
ASSERT_EQ (genesis, blocks[0]);
|
||||
}
|
||||
|
||||
TEST (rpc, frontier)
|
||||
{
|
||||
nano::system system (24000, 1);
|
||||
|
@ -2302,6 +2335,16 @@ TEST (rpc, successors)
|
|||
ASSERT_EQ (2, blocks.size ());
|
||||
ASSERT_EQ (genesis, blocks[0]);
|
||||
ASSERT_EQ (block->hash (), blocks[1]);
|
||||
// RPC chain "reverse" option
|
||||
request.put ("action", "chain");
|
||||
request.put ("reverse", "true");
|
||||
test_response response2 (request, rpc, system.io_ctx);
|
||||
while (response2.status == 0)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
ASSERT_EQ (200, response2.status);
|
||||
ASSERT_EQ (response.json, response2.json);
|
||||
}
|
||||
|
||||
TEST (rpc, bootstrap_any)
|
||||
|
|
|
@ -337,6 +337,19 @@ uint64_t nano::rpc_handler::count_optional_impl (uint64_t result)
|
|||
return result;
|
||||
}
|
||||
|
||||
uint64_t nano::rpc_handler::offset_optional_impl (uint64_t result)
|
||||
{
|
||||
boost::optional<std::string> offset_text (request.get_optional<std::string> ("offset"));
|
||||
if (!ec && offset_text.is_initialized ())
|
||||
{
|
||||
if (decode_unsigned (offset_text.get (), result))
|
||||
{
|
||||
ec = nano::error_rpc::invalid_offset;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool nano::rpc_handler::rpc_control_impl ()
|
||||
{
|
||||
bool result (false);
|
||||
|
@ -1388,8 +1401,10 @@ void nano::rpc_handler::bootstrap_status ()
|
|||
|
||||
void nano::rpc_handler::chain (bool successors)
|
||||
{
|
||||
successors = successors != request.get<bool> ("reverse", false);
|
||||
auto hash (hash_impl ("block"));
|
||||
auto count (count_impl ());
|
||||
auto offset (offset_optional_impl (0));
|
||||
if (!ec)
|
||||
{
|
||||
boost::property_tree::ptree blocks;
|
||||
|
@ -1399,9 +1414,16 @@ void nano::rpc_handler::chain (bool successors)
|
|||
auto block_l (node.store.block_get (transaction, hash));
|
||||
if (block_l != nullptr)
|
||||
{
|
||||
boost::property_tree::ptree entry;
|
||||
entry.put ("", hash.to_string ());
|
||||
blocks.push_back (std::make_pair ("", entry));
|
||||
if (offset > 0)
|
||||
{
|
||||
--offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::property_tree::ptree entry;
|
||||
entry.put ("", hash.to_string ());
|
||||
blocks.push_back (std::make_pair ("", entry));
|
||||
}
|
||||
hash = successors ? node.store.block_successor (transaction, hash) : block_l->previous ();
|
||||
}
|
||||
else
|
||||
|
@ -1841,50 +1863,42 @@ void nano::rpc_handler::account_history ()
|
|||
}
|
||||
}
|
||||
auto count (count_impl ());
|
||||
auto offset (offset_optional_impl (0));
|
||||
if (!ec)
|
||||
{
|
||||
uint64_t offset = 0;
|
||||
auto offset_text (request.get_optional<std::string> ("offset"));
|
||||
if (!offset_text || !decode_unsigned (*offset_text, offset))
|
||||
boost::property_tree::ptree history;
|
||||
response_l.put ("account", account.to_account ());
|
||||
auto block (node.store.block_get (transaction, hash));
|
||||
while (block != nullptr && count > 0)
|
||||
{
|
||||
boost::property_tree::ptree history;
|
||||
response_l.put ("account", account.to_account ());
|
||||
auto block (node.store.block_get (transaction, hash));
|
||||
while (block != nullptr && count > 0)
|
||||
if (offset > 0)
|
||||
{
|
||||
if (offset > 0)
|
||||
--offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::property_tree::ptree entry;
|
||||
history_visitor visitor (*this, output_raw, transaction, entry, hash);
|
||||
block->visit (visitor);
|
||||
if (!entry.empty ())
|
||||
{
|
||||
--offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::property_tree::ptree entry;
|
||||
history_visitor visitor (*this, output_raw, transaction, entry, hash);
|
||||
block->visit (visitor);
|
||||
if (!entry.empty ())
|
||||
entry.put ("hash", hash.to_string ());
|
||||
if (output_raw)
|
||||
{
|
||||
entry.put ("hash", hash.to_string ());
|
||||
if (output_raw)
|
||||
{
|
||||
entry.put ("work", nano::to_string_hex (block->block_work ()));
|
||||
entry.put ("signature", block->block_signature ().to_string ());
|
||||
}
|
||||
history.push_back (std::make_pair ("", entry));
|
||||
--count;
|
||||
entry.put ("work", nano::to_string_hex (block->block_work ()));
|
||||
entry.put ("signature", block->block_signature ().to_string ());
|
||||
}
|
||||
history.push_back (std::make_pair ("", entry));
|
||||
--count;
|
||||
}
|
||||
hash = block->previous ();
|
||||
block = node.store.block_get (transaction, hash);
|
||||
}
|
||||
response_l.add_child ("history", history);
|
||||
if (!hash.is_zero ())
|
||||
{
|
||||
response_l.put ("previous", hash.to_string ());
|
||||
}
|
||||
hash = block->previous ();
|
||||
block = node.store.block_get (transaction, hash);
|
||||
}
|
||||
else
|
||||
response_l.add_child ("history", history);
|
||||
if (!hash.is_zero ())
|
||||
{
|
||||
ec = nano::error_rpc::invalid_offset;
|
||||
response_l.put ("previous", hash.to_string ());
|
||||
}
|
||||
}
|
||||
response_errors ();
|
||||
|
|
|
@ -240,6 +240,7 @@ public:
|
|||
uint64_t work_optional_impl ();
|
||||
uint64_t count_impl ();
|
||||
uint64_t count_optional_impl (uint64_t = std::numeric_limits<uint64_t>::max ());
|
||||
uint64_t offset_optional_impl (uint64_t = 0);
|
||||
bool rpc_control_impl ();
|
||||
};
|
||||
/** Returns the correct RPC implementation based on TLS configuration */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue