RPC pending - sort by amount (#1748)
* Add 'sorting' option to 'pending' RPC. Change response to include the amount even if threshold is not provided. * Change to not break the RPC, response is still a list if using the simple version
This commit is contained in:
parent
8f4c02c196
commit
02db8a6dbf
2 changed files with 97 additions and 56 deletions
|
|
@ -1758,74 +1758,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);
|
||||
}
|
||||
request.put ("sorting", "true"); // Sorting 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 ());
|
||||
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, 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)
|
||||
{
|
||||
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 ());
|
||||
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 (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 ());
|
||||
}
|
||||
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 ());
|
||||
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 (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);
|
||||
}
|
||||
ASSERT_EQ (amounts[block1->hash ()], 100);
|
||||
ASSERT_EQ (sources[block1->hash ()], nano::test_genesis_key.pub);
|
||||
}
|
||||
|
||||
TEST (rpc_config, serialization)
|
||||
|
|
|
|||
|
|
@ -2319,6 +2319,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;
|
||||
|
|
@ -2328,7 +2330,7 @@ void nano::rpc_handler::pending ()
|
|||
nano::pending_key key (i->first);
|
||||
if (include_active || node.ledger.block_confirmed (transaction, key.hash))
|
||||
{
|
||||
if (threshold.is_zero () && !source && !min_version)
|
||||
if (simple)
|
||||
{
|
||||
boost::property_tree::ptree entry;
|
||||
entry.put ("", key.hash.to_string ());
|
||||
|
|
@ -2361,6 +2363,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 ();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue