From 15f9a461d6f7a0129340bfa40853da2aaefe141e Mon Sep 17 00:00:00 2001 From: theohax Date: Wed, 12 May 2021 11:45:59 +0300 Subject: [PATCH 1/4] Extend 'wallet_info' RPC command with two new keys: accounts_block_count and accounts_cemented_block_count Signed-off-by: theohax --- nano/node/json_handler.cpp | 28 +++++++++++++++++++++++++--- nano/rpc_test/rpc.cpp | 4 ++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 1d5f75277e..02ccbc08c0 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -4208,15 +4208,32 @@ void nano::json_handler::wallet_info () nano::uint128_t balance (0); nano::uint128_t pending (0); uint64_t count (0); + uint64_t block_count (0); + uint64_t cemented_block_count (0); uint64_t deterministic_count (0); uint64_t adhoc_count (0); auto transaction (node.wallets.tx_begin_read ()); auto block_transaction (node.store.tx_begin_read ()); + for (auto i (wallet->store.begin (transaction)), n (wallet->store.end ()); i != n; ++i) { nano::account const & account (i->first); - balance = balance + node.ledger.account_balance (block_transaction, account); - pending = pending + node.ledger.account_pending (block_transaction, account); + + nano::account_info account_info{}; + if (!node.store.account_get (block_transaction, account, account_info)) + { + block_count += account_info.block_count; + } + + nano::confirmation_height_info confirmation_info{}; + if (!node.store.confirmation_height_get (block_transaction, account, confirmation_info)) + { + cemented_block_count += confirmation_info.height; + } + + balance += node.ledger.account_balance (block_transaction, account); + pending += node.ledger.account_pending (block_transaction, account); + nano::key_type key_type (wallet->store.key_type (i->second)); if (key_type == nano::key_type::deterministic) { @@ -4226,16 +4243,21 @@ void nano::json_handler::wallet_info () { adhoc_count++; } - count++; + + ++count; } + uint32_t deterministic_index (wallet->store.deterministic_index_get (transaction)); response_l.put ("balance", balance.convert_to ()); response_l.put ("pending", pending.convert_to ()); response_l.put ("accounts_count", std::to_string (count)); + response_l.put ("accounts_block_count", std::to_string (block_count)); + response_l.put ("accounts_cemented_block_count", std::to_string (cemented_block_count)); response_l.put ("deterministic_count", std::to_string (deterministic_count)); response_l.put ("adhoc_count", std::to_string (adhoc_count)); response_l.put ("deterministic_index", std::to_string (deterministic_index)); } + response_errors (); } diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 32a21e3860..3029fd51f6 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -4128,6 +4128,10 @@ TEST (rpc, wallet_info) ASSERT_EQ ("1", pending_text); std::string count_text (response.json.get ("accounts_count")); ASSERT_EQ ("3", count_text); + std::string block_count_text (response.json.get ("accounts_block_count")); + ASSERT_EQ ("2", block_count_text); + std::string cemented_block_count_text (response.json.get ("accounts_cemented_block_count")); + ASSERT_EQ ("1", cemented_block_count_text); std::string adhoc_count (response.json.get ("adhoc_count")); ASSERT_EQ ("2", adhoc_count); std::string deterministic_count (response.json.get ("deterministic_count")); From 1d7be8d2ab9a1afa567406c50a2f8d55f9c53be2 Mon Sep 17 00:00:00 2001 From: theohax Date: Wed, 12 May 2021 13:10:17 +0300 Subject: [PATCH 2/4] Improvements to the 'wallet_info' RPC command test Signed-off-by: theohax --- nano/rpc_test/rpc.cpp | 95 +++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 3029fd51f6..8deac3b92c 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -4096,48 +4096,65 @@ TEST (rpc, blocks) TEST (rpc, wallet_info) { - nano::system system; - auto node = add_ipc_enabled_node (system); + nano::system system; + nano::node_config node_config (nano::get_available_port (), system.logging); + node_config.enable_voting = true; + auto node = add_ipc_enabled_node (system, node_config); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::keypair key; system.wallet (0)->insert_adhoc (key.prv); - auto send (system.wallet (0)->send_action (nano::dev_genesis_key.pub, key.pub, 1)); - nano::account account (system.wallet (0)->deterministic_insert ()); - { - auto transaction (node->wallets.tx_begin_write ()); - system.wallet (0)->store.erase (transaction, account); - } - account = system.wallet (0)->deterministic_insert (); - 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); - nano::rpc_config rpc_config (nano::get_available_port (), true); - rpc_config.rpc_process.ipc_port = node->config.ipc_config.transport_tcp.port; - 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", "wallet_info"); - request.put ("wallet", node->wallets.items.begin ()->first.to_string ()); - 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 ("balance")); - ASSERT_EQ ("340282366920938463463374607431768211454", balance_text); - std::string pending_text (response.json.get ("pending")); - ASSERT_EQ ("1", pending_text); - std::string count_text (response.json.get ("accounts_count")); - ASSERT_EQ ("3", count_text); - std::string block_count_text (response.json.get ("accounts_block_count")); - ASSERT_EQ ("2", block_count_text); - std::string cemented_block_count_text (response.json.get ("accounts_cemented_block_count")); - ASSERT_EQ ("1", cemented_block_count_text); - std::string adhoc_count (response.json.get ("adhoc_count")); - ASSERT_EQ ("2", adhoc_count); - std::string deterministic_count (response.json.get ("deterministic_count")); - ASSERT_EQ ("1", deterministic_count); - std::string index_text (response.json.get ("deterministic_index")); - ASSERT_EQ ("2", index_text); + + // at first, 1 block and 1 confirmed -- the genesis + ASSERT_EQ (1, node->ledger.cache.block_count); + ASSERT_EQ (1, node->ledger.cache.cemented_count); + + auto send (system.wallet (0)->send_action (nano::dev_genesis_key.pub, key.pub, nano::Gxrb_ratio)); + // after the send, expect 2 blocks immediately, then 2 confirmed in a timely manner, + // and finally 3 blocks and 3 confirmed after the wallet generates the receive block for this send + ASSERT_EQ (2, node->ledger.cache.block_count); + ASSERT_TIMELY (5s, 2 == node->ledger.cache.cemented_count); + ASSERT_TIMELY (5s, 3 == node->ledger.cache.block_count && 3 == node->ledger.cache.cemented_count); + + // do another send to be able to expect some "pending" down below + auto send2 (system.wallet (0)->send_action (nano::dev_genesis_key.pub, key.pub, 1)); + ASSERT_EQ (4, node->ledger.cache.block_count); + + nano::account account (system.wallet (0)->deterministic_insert ()); + { + auto transaction (node->wallets.tx_begin_write ()); + system.wallet (0)->store.erase (transaction, account); + } + account = system.wallet (0)->deterministic_insert (); + 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); + nano::rpc_config rpc_config (nano::get_available_port (), true); + rpc_config.rpc_process.ipc_port = node->config.ipc_config.transport_tcp.port; + 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", "wallet_info"); + request.put ("wallet", node->wallets.items.begin ()->first.to_string ()); + 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 ("balance")); + ASSERT_EQ ("340282366920938463463374607431768211454", balance_text); + std::string pending_text (response.json.get ("pending")); + ASSERT_EQ ("1", pending_text); + std::string count_text (response.json.get ("accounts_count")); + ASSERT_EQ ("3", count_text); + std::string block_count_text (response.json.get ("accounts_block_count")); + ASSERT_EQ ("4", block_count_text); + std::string cemented_block_count_text (response.json.get ("accounts_cemented_block_count")); + ASSERT_EQ ("3", cemented_block_count_text); + std::string adhoc_count (response.json.get ("adhoc_count")); + ASSERT_EQ ("2", adhoc_count); + std::string deterministic_count (response.json.get ("deterministic_count")); + ASSERT_EQ ("1", deterministic_count); + std::string index_text (response.json.get ("deterministic_index")); + ASSERT_EQ ("2", index_text); } TEST (rpc, wallet_balances) From 0e942be4c26ce1d0d53b2398250de9688655076b Mon Sep 17 00:00:00 2001 From: theohax Date: Wed, 12 May 2021 13:15:03 +0300 Subject: [PATCH 3/4] Fix formatting Signed-off-by: theohax --- nano/rpc_test/rpc.cpp | 98 +++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 8deac3b92c..8215e4a667 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -4096,65 +4096,65 @@ TEST (rpc, blocks) TEST (rpc, wallet_info) { - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = true; + nano::system system; + nano::node_config node_config (nano::get_available_port (), system.logging); + node_config.enable_voting = true; auto node = add_ipc_enabled_node (system, node_config); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::keypair key; system.wallet (0)->insert_adhoc (key.prv); // at first, 1 block and 1 confirmed -- the genesis - ASSERT_EQ (1, node->ledger.cache.block_count); - ASSERT_EQ (1, node->ledger.cache.cemented_count); + ASSERT_EQ (1, node->ledger.cache.block_count); + ASSERT_EQ (1, node->ledger.cache.cemented_count); auto send (system.wallet (0)->send_action (nano::dev_genesis_key.pub, key.pub, nano::Gxrb_ratio)); // after the send, expect 2 blocks immediately, then 2 confirmed in a timely manner, // and finally 3 blocks and 3 confirmed after the wallet generates the receive block for this send - ASSERT_EQ (2, node->ledger.cache.block_count); - ASSERT_TIMELY (5s, 2 == node->ledger.cache.cemented_count); - ASSERT_TIMELY (5s, 3 == node->ledger.cache.block_count && 3 == node->ledger.cache.cemented_count); - - // do another send to be able to expect some "pending" down below - auto send2 (system.wallet (0)->send_action (nano::dev_genesis_key.pub, key.pub, 1)); - ASSERT_EQ (4, node->ledger.cache.block_count); - - nano::account account (system.wallet (0)->deterministic_insert ()); - { - auto transaction (node->wallets.tx_begin_write ()); - system.wallet (0)->store.erase (transaction, account); - } - account = system.wallet (0)->deterministic_insert (); - 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); - nano::rpc_config rpc_config (nano::get_available_port (), true); - rpc_config.rpc_process.ipc_port = node->config.ipc_config.transport_tcp.port; - 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", "wallet_info"); - request.put ("wallet", node->wallets.items.begin ()->first.to_string ()); - 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 ("balance")); - ASSERT_EQ ("340282366920938463463374607431768211454", balance_text); - std::string pending_text (response.json.get ("pending")); - ASSERT_EQ ("1", pending_text); - std::string count_text (response.json.get ("accounts_count")); - ASSERT_EQ ("3", count_text); - std::string block_count_text (response.json.get ("accounts_block_count")); - ASSERT_EQ ("4", block_count_text); - std::string cemented_block_count_text (response.json.get ("accounts_cemented_block_count")); - ASSERT_EQ ("3", cemented_block_count_text); - std::string adhoc_count (response.json.get ("adhoc_count")); - ASSERT_EQ ("2", adhoc_count); - std::string deterministic_count (response.json.get ("deterministic_count")); - ASSERT_EQ ("1", deterministic_count); - std::string index_text (response.json.get ("deterministic_index")); - ASSERT_EQ ("2", index_text); + ASSERT_EQ (2, node->ledger.cache.block_count); + ASSERT_TIMELY (5s, 2 == node->ledger.cache.cemented_count); + ASSERT_TIMELY (5s, 3 == node->ledger.cache.block_count && 3 == node->ledger.cache.cemented_count); + + // do another send to be able to expect some "pending" down below + auto send2 (system.wallet (0)->send_action (nano::dev_genesis_key.pub, key.pub, 1)); + ASSERT_EQ (4, node->ledger.cache.block_count); + + nano::account account (system.wallet (0)->deterministic_insert ()); + { + auto transaction (node->wallets.tx_begin_write ()); + system.wallet (0)->store.erase (transaction, account); + } + account = system.wallet (0)->deterministic_insert (); + 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); + nano::rpc_config rpc_config (nano::get_available_port (), true); + rpc_config.rpc_process.ipc_port = node->config.ipc_config.transport_tcp.port; + 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", "wallet_info"); + request.put ("wallet", node->wallets.items.begin ()->first.to_string ()); + 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 ("balance")); + ASSERT_EQ ("340282366920938463463374607431768211454", balance_text); + std::string pending_text (response.json.get ("pending")); + ASSERT_EQ ("1", pending_text); + std::string count_text (response.json.get ("accounts_count")); + ASSERT_EQ ("3", count_text); + std::string block_count_text (response.json.get ("accounts_block_count")); + ASSERT_EQ ("4", block_count_text); + std::string cemented_block_count_text (response.json.get ("accounts_cemented_block_count")); + ASSERT_EQ ("3", cemented_block_count_text); + std::string adhoc_count (response.json.get ("adhoc_count")); + ASSERT_EQ ("2", adhoc_count); + std::string deterministic_count (response.json.get ("deterministic_count")); + ASSERT_EQ ("1", deterministic_count); + std::string index_text (response.json.get ("deterministic_index")); + ASSERT_EQ ("2", index_text); } TEST (rpc, wallet_balances) From 1027377a85330f9085fc687a6a42ca8fe569a0f7 Mon Sep 17 00:00:00 2001 From: theohax Date: Fri, 21 May 2021 13:22:23 +0300 Subject: [PATCH 4/4] Address code review --- nano/node/json_handler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 02ccbc08c0..9a49265247 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -4231,7 +4231,7 @@ void nano::json_handler::wallet_info () cemented_block_count += confirmation_info.height; } - balance += node.ledger.account_balance (block_transaction, account); + balance += account_info.balance; pending += node.ledger.account_pending (block_transaction, account); nano::key_type key_type (wallet->store.key_type (i->second));