Skip to content
New issue

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

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

Already on GitHub? # to your account

Return unopened accounts #4066

Merged
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions nano/node/json_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -899,20 +899,12 @@ void nano::json_handler::accounts_balances ()
auto account = account_impl (account_from_request.second.data ());
if (!ec)
{
nano::account_info info;
if (!node.store.account.get (transaction, account, info))
{
auto balance = node.balance_pending (account, false);
entry.put ("balance", balance.first.convert_to<std::string> ());
entry.put ("pending", balance.second.convert_to<std::string> ());
entry.put ("receivable", balance.second.convert_to<std::string> ());
balances.put_child (account_from_request.second.data (), entry);
continue;
}
else
{
ec = nano::error_common::account_not_found;
}
auto balance = node.balance_pending (account, false);
entry.put ("balance", balance.first.convert_to<std::string> ());
entry.put ("pending", balance.second.convert_to<std::string> ());
entry.put ("receivable", balance.second.convert_to<std::string> ());
balances.put_child (account_from_request.second.data (), entry);
continue;
}
entry.put ("error", ec.message ());
balances.put_child (account_from_request.second.data (), entry);
Expand Down
55 changes: 50 additions & 5 deletions nano/rpc_test/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3455,13 +3455,13 @@ 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 number for getting an error response.
// 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 that isn't on the ledger for getting an error response.
// Adds a valid account string that isn't on the ledger for getting an error response.
boost::property_tree::ptree entry3;
auto const account_not_found = "nano_1os6txqxyuesnxrtshnfb5or1hesc1647wpk9rsr84pmki6eairwha79hk3j";
entry3.put ("", account_not_found);
Expand All @@ -3482,17 +3482,62 @@ TEST (rpc, accounts_balances)
return ec.message ();
};

// Checking the account not found response
// 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 error_text1 = account_not_found_entry.get<std::string> ("error");
ASSERT_EQ (get_error_message (nano::error_common::account_not_found), error_text1);
auto account_balance_text = account_not_found_entry.get<std::string> ("balance");
ASSERT_EQ ("0", account_balance_text);
auto account_receivable_text = account_not_found_entry.get<std::string> ("receivable");
ASSERT_EQ ("0", account_receivable_text);

// 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<std::string> ("error");
ASSERT_EQ (get_error_message (nano::error_common::bad_account_number), error_text2);
}

/**
* Test the case where an account has no blocks at all (unopened) but has receivables
* In other words, sending to an a unopened account without receiving the funds
*/
TEST (rpc, accounts_balances_unopened_account_with_receivables)
{
nano::test::system system;
auto node = add_ipc_enabled_node (system);

// send a 1 raw to the unopened account which will have receivables
nano::keypair unopened_account;
auto send = nano::state_block_builder{}
.account (nano::dev::genesis_key.pub)
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - 1)
.link (unopened_account.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*node->work_generate_blocking (nano::dev::genesis->hash ()))
.build_shared ();
{
auto transaction (node->store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node->ledger.process (transaction, *send).code);
}
ASSERT_TIMELY (5s, node->block (send->hash ()));

// create and send the rpc request for the unopened account and wait for the response
auto const rpc_ctx = add_rpc (system, node);
boost::property_tree::ptree request;
boost::property_tree::ptree accounts_l;
boost::property_tree::ptree entry;
entry.put ("", unopened_account.pub.to_account ());
accounts_l.push_back (std::make_pair ("", entry));
request.add_child ("accounts", accounts_l);
request.put ("action", "accounts_balances");
auto response (wait_response (system, rpc_ctx, request));

// Check receivable amount
auto genesis_entry = response.get_child ("balances." + unopened_account.pub.to_account ());
ASSERT_EQ ("0", genesis_entry.get<std::string> ("balance"));
ASSERT_EQ ("1", genesis_entry.get<std::string> ("receivable"));
}

// Tests the happy path of retrieving an account's representative
TEST (rpc, accounts_representatives)
{
Expand Down