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 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"));
if (account_text.is_initialized ())
{
@ -4246,48 +4246,28 @@ void nano::json_handler::unopened ()
}
if (!ec)
{
auto transaction (node.store.tx_begin_read ());
auto iterator (node.store.pending.begin (transaction, nano::pending_key (start, 0)));
auto end (node.store.pending.end ());
nano::account current_account (start);
nano::uint128_t current_account_sum{ 0 };
auto transaction = node.store.tx_begin_read ();
auto & ledger = node.ledger;
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);
nano::account account (key.account);
nano::pending_info info (iterator->second);
if (node.store.account.exists (transaction, account))
auto const & [key, info] = *iterator;
nano::account account = key.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;
}
// 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;
}
auto const & [key, info] = *iterator;
current_account_sum += info.amount.number ();
++iterator;
}
}
// last one after iterator reaches end
if (accounts.size () < count && current_account_sum > 0 && current_account_sum >= threshold.number ())
if (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);
}