diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index c67878e2..ae029ac5 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -898,6 +898,7 @@ void nano::json_handler::account_weight () void nano::json_handler::accounts_balances () { boost::property_tree::ptree balances; + boost::property_tree::ptree errors; auto transaction = node.store.tx_begin_read (); for (auto & account_from_request : request.get_child ("accounts")) { @@ -913,11 +914,18 @@ void nano::json_handler::accounts_balances () balances.put_child (account_from_request.second.data (), entry); continue; } - entry.put ("error", ec.message ()); - balances.put_child (account_from_request.second.data (), entry); + debug_assert (ec); + errors.put (account_from_request.second.data (), ec.message ()); ec = {}; } - response_l.add_child ("balances", balances); + if (!balances.empty ()) + { + response_l.add_child ("balances", balances); + } + if (!errors.empty ()) + { + response_l.add_child ("errors", errors); + } response_errors (); } diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index b706020c..f14d5cbe 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -2902,17 +2902,11 @@ TEST (rpc, accounts_balances) entry1.put ("", nano::dev::genesis_key.pub.to_account ()); accounts_l.push_back (std::make_pair ("", entry1)); - // Adds a bad account string for getting an error response (the nano_ address checksum is wrong) - boost::property_tree::ptree entry2; - auto const bad_account_number = "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtd1"; - entry2.put ("", bad_account_number); - accounts_l.push_back (std::make_pair ("", entry2)); - // Adds a valid account string that isn't on the ledger for getting an error response. - boost::property_tree::ptree entry3; + boost::property_tree::ptree entry2; auto const account_not_found = "nano_1os6txqxyuesnxrtshnfb5or1hesc1647wpk9rsr84pmki6eairwha79hk3j"; - entry3.put ("", account_not_found); - accounts_l.push_back (std::make_pair ("", entry3)); + entry2.put ("", account_not_found); + accounts_l.push_back (std::make_pair ("", entry2)); request.add_child ("accounts", accounts_l); auto response (wait_response (system, rpc_ctx, request)); @@ -2924,11 +2918,6 @@ TEST (rpc, accounts_balances) auto receivable_text = genesis_entry.get ("receivable"); ASSERT_EQ ("0", receivable_text); - auto get_error_message = [] (nano::error_common error_common) -> std::string { - std::error_code ec = error_common; - return ec.message (); - }; - // Checking the account not found response - we do not distinguish between account not found and zero balance, zero receivables auto account_not_found_entry = response.get_child (boost::str (boost::format ("balances.%1%") % account_not_found)); auto account_balance_text = account_not_found_entry.get ("balance"); @@ -2936,10 +2925,49 @@ TEST (rpc, accounts_balances) auto account_receivable_text = account_not_found_entry.get ("receivable"); ASSERT_EQ ("0", account_receivable_text); + auto balances = response.get_child ("balances"); + ASSERT_EQ (2, balances.size ()); + + auto errors = response.get_child_optional ("errors"); + ASSERT_FALSE (errors.has_value ()); +} + +/** + * Test the RPC accounts_balances with 3 accounts, one good one, one with an invalid account ID and one with + * an account that does not exist. + */ +TEST (rpc, accounts_balances_with_errors) +{ + nano::test::system system; + auto node = add_ipc_enabled_node (system); + auto const rpc_ctx = add_rpc (system, node); + boost::property_tree::ptree request; + request.put ("action", "accounts_balances"); + boost::property_tree::ptree accounts_l; + + // Adds a bad account string for getting an error response (the nano_ address checksum is wrong) + boost::property_tree::ptree entry; + auto const bad_account_number = "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtd1"; + entry.put ("", bad_account_number); + accounts_l.push_back (std::make_pair ("", entry)); + + request.add_child ("accounts", accounts_l); + auto response (wait_response (system, rpc_ctx, request)); + + auto balances = response.get_child_optional ("balances"); + ASSERT_FALSE (balances.has_value ()); + + auto get_error_message = [] (nano::error_common error_common) -> std::string { + std::error_code ec = error_common; + return ec.message (); + }; + // Checking the bad account number response - auto bad_account_number_entry = response.get_child (boost::str (boost::format ("balances.%1%") % bad_account_number)); - auto error_text2 = bad_account_number_entry.get ("error"); - ASSERT_EQ (get_error_message (nano::error_common::bad_account_number), error_text2); + auto errors = response.get_child ("errors"); + ASSERT_EQ (1, errors.size ()); + ASSERT_EQ (1, errors.count (bad_account_number)); + auto bad_account_number_error_text = errors.get (bad_account_number); + ASSERT_EQ (get_error_message (nano::error_common::bad_account_number), bad_account_number_error_text); } /**