Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add include_only_confirmed to account_balance & account_info #3022

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
22 changes: 17 additions & 5 deletions nano/node/json_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,8 @@ void nano::json_handler::account_balance ()
auto account (account_impl ());
if (!ec)
{
auto balance (node.balance_pending (account));
const bool include_only_confirmed = request.get<bool> ("include_only_confirmed", false);
auto balance (node.balance_pending (account, include_only_confirmed));
response_l.put ("balance", balance.first.convert_to<std::string> ());
response_l.put ("pending", balance.second.convert_to<std::string> ());
}
Expand Down Expand Up @@ -602,6 +603,7 @@ void nano::json_handler::account_info ()
const bool representative = request.get<bool> ("representative", false);
const bool weight = request.get<bool> ("weight", false);
const bool pending = request.get<bool> ("pending", false);
const bool include_only_confirmed = request.get<bool> ("include_only_confirmed", false);
auto transaction (node.store.tx_begin_read ());
auto info (account_info_impl (transaction, account));
nano::confirmation_height_info confirmation_height_info;
Expand All @@ -614,8 +616,18 @@ void nano::json_handler::account_info ()
response_l.put ("frontier", info.head.to_string ());
response_l.put ("open_block", info.open_block.to_string ());
response_l.put ("representative_block", node.ledger.representative (transaction, info.head).to_string ());
nano::amount balance_l (info.balance);
if (include_only_confirmed)
{
balance_l = node.ledger.balance (transaction, confirmation_height_info.frontier);
}
else
{
balance_l = info.balance;
}
std::string balance;
nano::uint128_union (info.balance).encode_dec (balance);
balance_l.encode_dec (balance);

response_l.put ("balance", balance);
response_l.put ("modified_timestamp", std::to_string (info.modified));
response_l.put ("block_count", std::to_string (info.block_count));
Expand All @@ -633,7 +645,7 @@ void nano::json_handler::account_info ()
}
if (pending)
{
auto account_pending (node.ledger.account_pending (transaction, account));
auto account_pending (node.ledger.account_pending (transaction, account, include_only_confirmed));
response_l.put ("pending", account_pending.convert_to<std::string> ());
}
}
Expand Down Expand Up @@ -829,7 +841,7 @@ void nano::json_handler::accounts_balances ()
if (!ec)
{
boost::property_tree::ptree entry;
auto balance (node.balance_pending (account));
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> ());
balances.push_back (std::make_pair (account.to_account (), entry));
Expand Down Expand Up @@ -986,7 +998,7 @@ void nano::json_handler::available_supply ()
auto genesis_balance (node.balance (node.network_params.ledger.genesis_account)); // Cold storage genesis
auto landing_balance (node.balance (nano::account ("059F68AAB29DE0D3A27443625C7EA9CDDB6517A8B76FE37727EF6A4D76832AD5"))); // Active unavailable account
auto faucet_balance (node.balance (nano::account ("8E319CE6F3025E5B2DF66DA7AB1467FE48F1679C13DD43BFDB29FA2E9FC40D3B"))); // Faucet account
auto burned_balance ((node.balance_pending (nano::account (0))).second); // Burning 0 account
auto burned_balance ((node.balance_pending (nano::account (0), false)).second); // Burning 0 account
auto available (node.network_params.ledger.genesis_amount - genesis_balance - landing_balance - faucet_balance - burned_balance);
response_l.put ("available", available.convert_to<std::string> ());
response_errors ();
Expand Down
6 changes: 3 additions & 3 deletions nano/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,12 +753,12 @@ std::shared_ptr<nano::block> nano::node::block (nano::block_hash const & hash_a)
return store.block_get (transaction, hash_a);
}

std::pair<nano::uint128_t, nano::uint128_t> nano::node::balance_pending (nano::account const & account_a)
std::pair<nano::uint128_t, nano::uint128_t> nano::node::balance_pending (nano::account const & account_a, bool only_confirmed_a)
{
std::pair<nano::uint128_t, nano::uint128_t> result;
auto transaction (store.tx_begin_read ());
result.first = ledger.account_balance (transaction, account_a);
result.second = ledger.account_pending (transaction, account_a);
result.first = ledger.account_balance (transaction, account_a, only_confirmed_a);
result.second = ledger.account_pending (transaction, account_a, only_confirmed_a);
return result;
}

Expand Down
2 changes: 1 addition & 1 deletion nano/node/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class node final : public std::enable_shared_from_this<nano::node>
nano::block_hash latest (nano::account const &);
nano::uint128_t balance (nano::account const &);
std::shared_ptr<nano::block> block (nano::block_hash const &);
std::pair<nano::uint128_t, nano::uint128_t> balance_pending (nano::account const &);
std::pair<nano::uint128_t, nano::uint128_t> balance_pending (nano::account const &, bool only_confirmed);
nano::uint128_t weight (nano::account const &);
nano::block_hash rep_block (nano::account const &);
nano::uint128_t minimum_principal_weight ();
Expand Down
6 changes: 3 additions & 3 deletions nano/qt/qt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ wallet (wallet_a)
{
show_line_ok (*account_line);
this->history.refresh ();
auto balance (this->wallet.node.balance_pending (account));
auto balance (this->wallet.node.balance_pending (account, false));
auto final_text (std::string ("Balance (NANO): ") + wallet.format_balance (balance.first));
if (!balance.second.is_zero ())
{
Expand Down Expand Up @@ -1105,7 +1105,7 @@ void nano_qt::wallet::ongoing_refresh ()
if (needs_balance_refresh)
{
needs_balance_refresh = false;
auto balance_l (node.balance_pending (account));
auto balance_l (node.balance_pending (account, false));
application.postEvent (&processor, new eventloop_event ([wallet_w, balance_l]() {
if (auto this_l = wallet_w.lock ())
{
Expand Down Expand Up @@ -1451,7 +1451,7 @@ void nano_qt::wallet::change_rendering_ratio (nano::uint128_t const & rendering_
{
application.postEvent (&processor, new eventloop_event ([this, rendering_ratio_a]() {
this->rendering_ratio = rendering_ratio_a;
auto balance_l (this->node.balance_pending (account));
auto balance_l (this->node.balance_pending (account, false));
this->self.set_balance_text (balance_l);
this->refresh ();
}));
Expand Down
92 changes: 85 additions & 7 deletions nano/rpc_test/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,22 @@ TEST (rpc, account_balance)
{
nano::system system;
auto node = add_ipc_enabled_node (system);

// Add a send block (which will add a pending entry too) for the genesis account
nano::state_block_builder builder;

auto send1 = builder.make_block ()
.account (nano::dev_genesis_key.pub)
.previous (nano::genesis_hash)
.representative (nano::dev_genesis_key.pub)
.balance (nano::genesis_amount - 1)
.link (nano::dev_genesis_key.pub)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (*system.work.generate (nano::genesis_hash))
.build ();

ASSERT_EQ (nano::process_result::progress, node->process (*send1).code);

scoped_io_thread_name_change scoped_thread_name_io;
nano::node_rpc_config node_rpc_config;
nano::ipc::ipc_server ipc_server (*node, node_rpc_config);
Expand All @@ -176,16 +192,31 @@ TEST (rpc, account_balance)
nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config);
nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor);
rpc.start ();

boost::property_tree::ptree request;
request.put ("action", "account_balance");
request.put ("account", nano::dev_genesis_key.pub.to_account ());
test_response response (request, rpc.config.port, system.io_ctx);
ASSERT_TIMELY (5s, response.status != 0);
ASSERT_EQ (200, response.status);
std::string balance_text (response.json.get<std::string> ("balance"));
ASSERT_EQ ("340282366920938463463374607431768211455", balance_text);
std::string pending_text (response.json.get<std::string> ("pending"));
ASSERT_EQ ("0", pending_text);
{
test_response response (request, rpc.config.port, system.io_ctx);
ASSERT_TIMELY (5s, response.status != 0);
ASSERT_EQ (200, response.status);
std::string balance_text (response.json.get<std::string> ("balance"));
ASSERT_EQ ("340282366920938463463374607431768211454", balance_text);
std::string pending_text (response.json.get<std::string> ("pending"));
ASSERT_EQ ("1", pending_text);
}

// The send and pending should be unconfirmed
request.put ("include_only_confirmed", true);
{
test_response response (request, rpc.config.port, system.io_ctx);
ASSERT_TIMELY (5s, response.status != 0);
ASSERT_EQ (200, response.status);
std::string balance_text (response.json.get<std::string> ("balance"));
ASSERT_EQ ("340282366920938463463374607431768211455", balance_text);
std::string pending_text (response.json.get<std::string> ("pending"));
ASSERT_EQ ("0", pending_text);
}
}

TEST (rpc, account_block_count)
Expand Down Expand Up @@ -5052,6 +5083,53 @@ TEST (rpc, account_info)
std::string representative2 (response.json.get<std::string> ("representative"));
ASSERT_EQ (nano::dev_genesis_key.pub.to_account (), representative2);
}

// Test for confirmed only blocks
scoped_thread_name_io.reset ();
nano::keypair key1;
{
latest = node1.latest (nano::dev_genesis_key.pub);
nano::send_block send1 (latest, key1.pub, 50, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest));
node1.process (send1);
nano::send_block send2 (send1.hash (), key1.pub, 25, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (send1.hash ()));
node1.process (send2);

nano::open_block open (send1.hash (), nano::dev_genesis_key.pub, key1.pub, key1.prv, key1.pub, *node1.work_generate_blocking (key1.pub));
node1.process (open);
}

scoped_thread_name_io.renew ();

{
test_response response (request, rpc.config.port, system.io_ctx);
ASSERT_TIMELY (5s, response.status != 0);
std::string balance (response.json.get<std::string> ("balance"));
ASSERT_EQ ("25", balance);
}

request.put ("include_only_confirmed", true);
{
test_response response (request, rpc.config.port, system.io_ctx);
ASSERT_TIMELY (5s, response.status != 0);
std::string balance (response.json.get<std::string> ("balance"));
ASSERT_EQ ("340282366920938463463374607431768211455", balance);
}

request.put ("account", key1.pub.to_account ());
{
test_response response (request, rpc.config.port, system.io_ctx);
ASSERT_TIMELY (5s, response.status != 0);
std::string pending (response.json.get<std::string> ("pending"));
ASSERT_EQ ("0", pending);
}

request.put ("include_only_confirmed", false);
{
test_response response (request, rpc.config.port, system.io_ctx);
ASSERT_TIMELY (5s, response.status != 0);
std::string pending (response.json.get<std::string> ("pending"));
ASSERT_EQ ("25", pending);
}
}

/** Make sure we can use json block literals instead of string as input */
Expand Down
35 changes: 28 additions & 7 deletions nano/secure/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -826,26 +826,47 @@ nano::uint128_t nano::ledger::balance_safe (nano::transaction const & transactio
}

// Balance for an account by account number
nano::uint128_t nano::ledger::account_balance (nano::transaction const & transaction_a, nano::account const & account_a)
nano::uint128_t nano::ledger::account_balance (nano::transaction const & transaction_a, nano::account const & account_a, bool only_confirmed_a)
{
nano::uint128_t result (0);
nano::account_info info;
auto none (store.account_get (transaction_a, account_a, info));
if (!none)
if (only_confirmed_a)
{
nano::confirmation_height_info info;
if (!store.confirmation_height_get (transaction_a, account_a, info))
{
result = balance (transaction_a, info.frontier);
}
}
else
{
result = info.balance.number ();
nano::account_info info;
auto none (store.account_get (transaction_a, account_a, info));
if (!none)
{
result = info.balance.number ();
}
}
return result;
}

nano::uint128_t nano::ledger::account_pending (nano::transaction const & transaction_a, nano::account const & account_a)
nano::uint128_t nano::ledger::account_pending (nano::transaction const & transaction_a, nano::account const & account_a, bool only_confirmed_a)
{
nano::uint128_t result (0);
nano::account end (account_a.number () + 1);
for (auto i (store.pending_begin (transaction_a, nano::pending_key (account_a, 0))), n (store.pending_begin (transaction_a, nano::pending_key (end, 0))); i != n; ++i)
{
nano::pending_info const & info (i->second);
result += info.amount.number ();
if (only_confirmed_a)
{
if (block_confirmed (transaction_a, i->first.hash))
cryptocode marked this conversation as resolved.
Show resolved Hide resolved
{
result += info.amount.number ();
}
}
else
{
result += info.amount.number ();
}
}
return result;
}
Expand Down
4 changes: 2 additions & 2 deletions nano/secure/ledger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class ledger final
nano::uint128_t amount_safe (nano::transaction const &, nano::block_hash const & hash_a, bool &) const;
nano::uint128_t balance (nano::transaction const &, nano::block_hash const &) const;
nano::uint128_t balance_safe (nano::transaction const &, nano::block_hash const &, bool &) const;
nano::uint128_t account_balance (nano::transaction const &, nano::account const &);
nano::uint128_t account_pending (nano::transaction const &, nano::account const &);
nano::uint128_t account_balance (nano::transaction const &, nano::account const &, bool = false);
nano::uint128_t account_pending (nano::transaction const &, nano::account const &, bool = false);
nano::uint128_t weight (nano::account const &);
std::shared_ptr<nano::block> successor (nano::transaction const &, nano::qualified_root const &);
std::shared_ptr<nano::block> forked_block (nano::transaction const &, nano::block const &);
Expand Down