Rewrite json_handler::unopened in terms of receivable iterators

The algorithm had a non-trivial change to implementation. The intent is to sum the amount of balance receivable for given set of accounts. The region selected starts at "account" and ends when "count" is reached.
This commit is contained in:
Colin LeMahieu 2024-03-16 19:24:17 +00:00
commit d58316451a
No known key found for this signature in database
GPG key ID: 43708520C8DFB938

View file

@ -4238,7 +4238,7 @@ void nano::json_handler::unopened ()
{ {
auto count (count_optional_impl ()); auto count (count_optional_impl ());
auto threshold (threshold_optional_impl ()); auto threshold (threshold_optional_impl ());
nano::account start (1); // exclude burn account by default nano::account start{ 1 }; // exclude burn account by default
boost::optional<std::string> account_text (request.get_optional<std::string> ("account")); boost::optional<std::string> account_text (request.get_optional<std::string> ("account"));
if (account_text.is_initialized ()) if (account_text.is_initialized ())
{ {
@ -4246,48 +4246,28 @@ void nano::json_handler::unopened ()
} }
if (!ec) if (!ec)
{ {
auto transaction (node.store.tx_begin_read ()); auto transaction = node.store.tx_begin_read ();
auto iterator (node.store.pending.begin (transaction, nano::pending_key (start, 0))); auto & ledger = node.ledger;
auto end (node.store.pending.end ());
nano::account current_account (start);
nano::uint128_t current_account_sum{ 0 };
boost::property_tree::ptree accounts; boost::property_tree::ptree accounts;
while (iterator != end && accounts.size () < count) for (auto iterator = ledger.receivable_upper_bound (transaction, start, 0), end = ledger.receivable_end (); iterator != end && accounts.size () < count;)
{ {
nano::pending_key key (iterator->first); auto const & [key, info] = *iterator;
nano::account account (key.account); nano::account account = key.account;
nano::pending_info info (iterator->second); if (!node.store.account.exists (transaction, account))
if (node.store.account.exists (transaction, account))
{ {
if (account.number () == std::numeric_limits<nano::uint256_t>::max ()) nano::uint128_t current_account_sum{ 0 };
while (iterator != end)
{ {
break; auto const & [key, info] = *iterator;
}
// Skip existing accounts
iterator = node.store.pending.begin (transaction, nano::pending_key (account.number () + 1, 0));
}
else
{
if (account != current_account)
{
if (current_account_sum > 0)
{
if (current_account_sum >= threshold.number ())
{
accounts.put (current_account.to_account (), current_account_sum.convert_to<std::string> ());
}
current_account_sum = 0;
}
current_account = account;
}
current_account_sum += info.amount.number (); current_account_sum += info.amount.number ();
++iterator; ++iterator;
} }
} if (current_account_sum >= threshold.number ())
// last one after iterator reaches end
if (accounts.size () < count && current_account_sum > 0 && current_account_sum >= threshold.number ())
{ {
accounts.put (current_account.to_account (), current_account_sum.convert_to<std::string> ()); accounts.put (account.to_account (), current_account_sum.convert_to<std::string> ());
}
}
iterator = ledger.receivable_upper_bound (transaction, account);
} }
response_l.add_child ("accounts", accounts); response_l.add_child ("accounts", accounts);
} }