Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPC pending - sort by amount #1748

Merged
merged 2 commits into from Mar 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
134 changes: 79 additions & 55 deletions nano/core_test/rpc.cpp
Expand Up @@ -1752,74 +1752,98 @@ TEST (rpc, pending)
request.put ("action", "pending");
request.put ("account", key1.pub.to_account ());
request.put ("count", "100");
test_response response (request, rpc, system.io_ctx);
system.deadline_set (5s);
while (response.status == 0)
{
ASSERT_NO_ERROR (system.poll ());
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"));
ASSERT_EQ (1, blocks_node.size ());
nano::block_hash hash (blocks_node.begin ()->second.get<std::string> (""));
ASSERT_EQ (block1->hash (), hash);
}
ASSERT_EQ (200, response.status);
auto & blocks_node (response.json.get_child ("blocks"));
ASSERT_EQ (1, blocks_node.size ());
nano::block_hash hash1 (blocks_node.begin ()->second.get<std::string> (""));
ASSERT_EQ (block1->hash (), hash1);
request.put ("threshold", "100"); // Threshold test
test_response response0 (request, rpc, system.io_ctx);
system.deadline_set (5s);
while (response0.status == 0)
request.put ("sorting", "true"); // Sorting test
{
ASSERT_NO_ERROR (system.poll ());
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"));
ASSERT_EQ (1, blocks_node.size ());
nano::block_hash hash (blocks_node.begin ()->first);
ASSERT_EQ (block1->hash (), hash);
std::string amount (blocks_node.begin ()->second.get<std::string> (""));
ASSERT_EQ ("100", amount);
}
ASSERT_EQ (200, response0.status);
blocks_node = response0.json.get_child ("blocks");
ASSERT_EQ (1, blocks_node.size ());
std::unordered_map<nano::block_hash, nano::uint128_union> blocks;
for (auto i (blocks_node.begin ()), j (blocks_node.end ()); i != j; ++i)
{
nano::block_hash hash;
hash.decode_hex (i->first);
nano::uint128_union amount;
amount.decode_dec (i->second.get<std::string> (""));
blocks[hash] = amount;
boost::optional<std::string> source (i->second.get_optional<std::string> ("source"));
ASSERT_FALSE (source.is_initialized ());
boost::optional<uint8_t> min_version (i->second.get_optional<uint8_t> ("min_version"));
ASSERT_FALSE (min_version.is_initialized ());
request.put ("threshold", "100"); // Threshold test
{
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"));
ASSERT_EQ (1, blocks_node.size ());
std::unordered_map<nano::block_hash, nano::uint128_union> blocks;
for (auto i (blocks_node.begin ()), j (blocks_node.end ()); i != j; ++i)
{
nano::block_hash hash;
hash.decode_hex (i->first);
nano::uint128_union amount;
amount.decode_dec (i->second.get<std::string> (""));
blocks[hash] = amount;
boost::optional<std::string> source (i->second.get_optional<std::string> ("source"));
ASSERT_FALSE (source.is_initialized ());
boost::optional<uint8_t> min_version (i->second.get_optional<uint8_t> ("min_version"));
ASSERT_FALSE (min_version.is_initialized ());
}
ASSERT_EQ (blocks[block1->hash ()], 100);
}
ASSERT_EQ (blocks[block1->hash ()], 100);
request.put ("threshold", "101");
test_response response1 (request, rpc, system.io_ctx);
while (response1.status == 0)
{
ASSERT_NO_ERROR (system.poll ());
test_response response (request, rpc, system.io_ctx);
while (response.status == 0)
{
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_EQ (200, response.status);
auto & blocks_node (response.json.get_child ("blocks"));
ASSERT_EQ (0, blocks_node.size ());
}
ASSERT_EQ (200, response1.status);
blocks_node = response1.json.get_child ("blocks");
ASSERT_EQ (0, blocks_node.size ());
request.put ("threshold", "0");
request.put ("source", "true");
request.put ("min_version", "true");
test_response response2 (request, rpc, system.io_ctx);
system.deadline_set (5s);
while (response2.status == 0)
{
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_EQ (200, response2.status);
blocks_node = response2.json.get_child ("blocks");
ASSERT_EQ (1, blocks_node.size ());
std::unordered_map<nano::block_hash, nano::uint128_union> amounts;
std::unordered_map<nano::block_hash, nano::account> sources;
for (auto i (blocks_node.begin ()), j (blocks_node.end ()); i != j; ++i)
{
nano::block_hash hash;
hash.decode_hex (i->first);
amounts[hash].decode_dec (i->second.get<std::string> ("amount"));
sources[hash].decode_account (i->second.get<std::string> ("source"));
ASSERT_EQ (i->second.get<uint8_t> ("min_version"), 0);
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"));
ASSERT_EQ (1, blocks_node.size ());
std::unordered_map<nano::block_hash, nano::uint128_union> amounts;
std::unordered_map<nano::block_hash, nano::account> sources;
for (auto i (blocks_node.begin ()), j (blocks_node.end ()); i != j; ++i)
{
nano::block_hash hash;
hash.decode_hex (i->first);
amounts[hash].decode_dec (i->second.get<std::string> ("amount"));
sources[hash].decode_account (i->second.get<std::string> ("source"));
ASSERT_EQ (i->second.get<uint8_t> ("min_version"), 0);
}
ASSERT_EQ (amounts[block1->hash ()], 100);
ASSERT_EQ (sources[block1->hash ()], nano::test_genesis_key.pub);
}
ASSERT_EQ (amounts[block1->hash ()], 100);
ASSERT_EQ (sources[block1->hash ()], nano::test_genesis_key.pub);
}

TEST (rpc_config, serialization)
Expand Down
19 changes: 18 additions & 1 deletion nano/node/rpc.cpp
Expand Up @@ -2264,6 +2264,8 @@ void nano::rpc_handler::pending ()
const bool source = request.get<bool> ("source", false);
const bool min_version = request.get<bool> ("min_version", false);
const bool include_active = request.get<bool> ("include_active", false);
const bool sorting = request.get<bool> ("sorting", false);
auto simple (threshold.is_zero () && !source && !min_version && !sorting); // if simple, response is a list of hashes
if (!ec)
{
boost::property_tree::ptree peers_l;
Expand All @@ -2274,7 +2276,7 @@ void nano::rpc_handler::pending ()
std::shared_ptr<nano::block> block (include_active ? nullptr : node.store.block_get (transaction, key.hash));
if (include_active || (block && !node.active.active (*block)))
{
if (threshold.is_zero () && !source && !min_version)
if (simple)
{
boost::property_tree::ptree entry;
entry.put ("", key.hash.to_string ());
Expand Down Expand Up @@ -2307,6 +2309,21 @@ void nano::rpc_handler::pending ()
}
}
}
if (sorting && !simple)
{
if (source || min_version)
{
peers_l.sort ([](const auto & child1, const auto & child2) -> bool {
return child1.second.template get<nano::uint128_t> ("amount") > child2.second.template get<nano::uint128_t> ("amount");
});
}
else
{
peers_l.sort ([](const auto & child1, const auto & child2) -> bool {
return child1.second.template get<nano::uint128_t> ("") > child2.second.template get<nano::uint128_t> ("");
});
}
}
response_l.add_child ("blocks", peers_l);
}
response_errors ();
Expand Down