Pending to receivable renames (#3753)

* Copy accounts_pending to accounts_receivable and deprecate the former

* Copy wallet_pending to wallet_receivable and deprecate the former

* Copy search_pending_all to search_receivable_all and deprecate the former

* Copy search_pending to search_receivable and deprecate the former

* account_info rpc: introduce receivable option and confirmed_receivable reply

Introduce new option called receivable to replace pending option.
Currently both are supported and do the same job.
However, if both are set, receivable has priority.

Also added confirmed_receivable reply when include_confirmed is set.

* Rename nano:📒:account_pending to nano:📒:account_receivable

* Convert RPC blocks_info to use receivable rather than pending

Pending is still supported but deprecated

* Add support for receivable option to ledger RPC command

The ledger RPC command only supported pending option.
Now, it supports both with receivable having priority, if both are set.

* Add support for receivable option to wallet_ledger RPC command

* Add deprecated field in RPC response of pending and pending_exists

The RPC commands did not return "deprecated=true", now they do.
Also renamed underlying handling functions from pending to receivable.
This commit is contained in:
Dimitrios Siganos 2022-03-28 13:07:02 +01:00 committed by GitHub
commit a37a1480d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 201 additions and 107 deletions

View file

@ -107,7 +107,7 @@ TEST (ledger, process_send)
ASSERT_EQ (nano::process_result::progress, return1.code);
ASSERT_EQ (nano::dev::genesis_key.pub, store->block.account_calculated (send));
ASSERT_EQ (50, ledger.account_balance (transaction, nano::dev::genesis_key.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.account_pending (transaction, key2.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.account_receivable (transaction, key2.pub));
nano::account_info info2;
ASSERT_FALSE (store->account.get (transaction, nano::dev::genesis_key.pub, info2));
ASSERT_EQ (2, info2.block_count);
@ -131,7 +131,7 @@ TEST (ledger, process_send)
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.amount (transaction, hash2));
ASSERT_EQ (key2.pub, store->frontier.get (transaction, hash2));
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.account_balance (transaction, key2.pub));
ASSERT_EQ (0, ledger.account_pending (transaction, key2.pub));
ASSERT_EQ (0, ledger.account_receivable (transaction, key2.pub));
ASSERT_EQ (50, ledger.weight (nano::dev::genesis_key.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.weight (key2.pub));
nano::account_info info3;
@ -157,7 +157,7 @@ TEST (ledger, process_send)
ASSERT_EQ (nano::dev::genesis_key.pub, pending1.source);
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, pending1.amount.number ());
ASSERT_EQ (0, ledger.account_balance (transaction, key2.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.account_pending (transaction, key2.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.account_receivable (transaction, key2.pub));
ASSERT_EQ (50, ledger.account_balance (transaction, nano::dev::genesis_key.pub));
ASSERT_EQ (50, ledger.weight (nano::dev::genesis_key.pub));
ASSERT_EQ (0, ledger.weight (key2.pub));
@ -175,7 +175,7 @@ TEST (ledger, process_send)
nano::pending_info pending2;
ASSERT_TRUE (ledger.store.pending.get (transaction, nano::pending_key (key2.pub, hash1), pending2));
ASSERT_EQ (nano::dev::constants.genesis_amount, ledger.account_balance (transaction, nano::dev::genesis_key.pub));
ASSERT_EQ (0, ledger.account_pending (transaction, key2.pub));
ASSERT_EQ (0, ledger.account_receivable (transaction, key2.pub));
ASSERT_EQ (store->account.count (transaction), ledger.cache.account_count);
}
@ -223,7 +223,7 @@ TEST (ledger, process_receive)
ASSERT_EQ (key2.pub, store->block.account_calculated (receive));
ASSERT_EQ (hash4, ledger.latest (transaction, key2.pub));
ASSERT_EQ (25, ledger.account_balance (transaction, nano::dev::genesis_key.pub));
ASSERT_EQ (0, ledger.account_pending (transaction, key2.pub));
ASSERT_EQ (0, ledger.account_receivable (transaction, key2.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 25, ledger.account_balance (transaction, key2.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 25, ledger.weight (key3.pub));
ASSERT_FALSE (ledger.rollback (transaction, hash4));
@ -231,7 +231,7 @@ TEST (ledger, process_receive)
ASSERT_EQ (key2.pub, store->frontier.get (transaction, hash2));
ASSERT_TRUE (store->frontier.get (transaction, hash4).is_zero ());
ASSERT_EQ (25, ledger.account_balance (transaction, nano::dev::genesis_key.pub));
ASSERT_EQ (25, ledger.account_pending (transaction, key2.pub));
ASSERT_EQ (25, ledger.account_receivable (transaction, key2.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.account_balance (transaction, key2.pub));
ASSERT_EQ (nano::dev::constants.genesis_amount - 50, ledger.weight (key3.pub));
ASSERT_EQ (hash2, ledger.latest (transaction, key2.pub));

View file

@ -381,7 +381,7 @@ TEST (node, merge_peers)
ASSERT_EQ (0, system.nodes[0]->network.size ());
}
TEST (node, search_pending)
TEST (node, search_receivable)
{
nano::system system (1);
auto node (system.nodes[0]);
@ -389,11 +389,11 @@ TEST (node, search_pending)
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node->config.receive_minimum.number ()));
system.wallet (0)->insert_adhoc (key2.prv);
ASSERT_FALSE (system.wallet (0)->search_pending (system.wallet (0)->wallets.tx_begin_read ()));
ASSERT_FALSE (system.wallet (0)->search_receivable (system.wallet (0)->wallets.tx_begin_read ()));
ASSERT_TIMELY (10s, !node->balance (key2.pub).is_zero ());
}
TEST (node, search_pending_same)
TEST (node, search_receivable_same)
{
nano::system system (1);
auto node (system.nodes[0]);
@ -402,11 +402,11 @@ TEST (node, search_pending_same)
ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node->config.receive_minimum.number ()));
ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node->config.receive_minimum.number ()));
system.wallet (0)->insert_adhoc (key2.prv);
ASSERT_FALSE (system.wallet (0)->search_pending (system.wallet (0)->wallets.tx_begin_read ()));
ASSERT_FALSE (system.wallet (0)->search_receivable (system.wallet (0)->wallets.tx_begin_read ()));
ASSERT_TIMELY (10s, node->balance (key2.pub) == 2 * node->config.receive_minimum.number ());
}
TEST (node, search_pending_multiple)
TEST (node, search_receivable_multiple)
{
nano::system system (1);
auto node (system.nodes[0]);
@ -419,11 +419,11 @@ TEST (node, search_pending_multiple)
ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node->config.receive_minimum.number ()));
ASSERT_NE (nullptr, system.wallet (0)->send_action (key3.pub, key2.pub, node->config.receive_minimum.number ()));
system.wallet (0)->insert_adhoc (key2.prv);
ASSERT_FALSE (system.wallet (0)->search_pending (system.wallet (0)->wallets.tx_begin_read ()));
ASSERT_FALSE (system.wallet (0)->search_receivable (system.wallet (0)->wallets.tx_begin_read ()));
ASSERT_TIMELY (10s, node->balance (key2.pub) == 2 * node->config.receive_minimum.number ());
}
TEST (node, search_pending_confirmed)
TEST (node, search_receivable_confirmed)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
@ -449,7 +449,7 @@ TEST (node, search_pending_confirmed)
system.wallet (0)->store.erase (transaction, nano::dev::genesis_key.pub);
}
system.wallet (0)->insert_adhoc (key2.prv);
ASSERT_FALSE (system.wallet (0)->search_pending (system.wallet (0)->wallets.tx_begin_read ()));
ASSERT_FALSE (system.wallet (0)->search_receivable (system.wallet (0)->wallets.tx_begin_read ()));
{
nano::lock_guard<nano::mutex> guard (node->active.mutex);
auto existing1 (node->active.blocks.find (send1->hash ()));
@ -460,7 +460,7 @@ TEST (node, search_pending_confirmed)
ASSERT_TIMELY (10s, node->balance (key2.pub) == 2 * node->config.receive_minimum.number ());
}
TEST (node, search_pending_pruned)
TEST (node, search_receivable_pruned)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
@ -494,7 +494,7 @@ TEST (node, search_pending_pruned)
// Receive pruned block
system.wallet (1)->insert_adhoc (key2.prv);
ASSERT_FALSE (system.wallet (1)->search_pending (system.wallet (1)->wallets.tx_begin_read ()));
ASSERT_FALSE (system.wallet (1)->search_receivable (system.wallet (1)->wallets.tx_begin_read ()));
ASSERT_TIMELY (10s, node2->balance (key2.pub) == 2 * node2->config.receive_minimum.number ());
}

View file

@ -1152,7 +1152,7 @@ TEST (wallet, foreach_representative_deadlock)
ASSERT_TRUE (set);
}
TEST (wallet, search_pending)
TEST (wallet, search_receivable)
{
nano::system system;
nano::node_config config (nano::get_available_port (), system.logging);
@ -1178,7 +1178,7 @@ TEST (wallet, search_pending)
// Pending search should start an election
ASSERT_TRUE (node.active.empty ());
ASSERT_FALSE (wallet.search_pending (wallet.wallets.tx_begin_read ()));
ASSERT_FALSE (wallet.search_receivable (wallet.wallets.tx_begin_read ()));
auto election = node.active.election (send->qualified_root ());
ASSERT_NE (nullptr, election);
@ -1195,7 +1195,7 @@ TEST (wallet, search_pending)
// Pending search should create the receive block
ASSERT_EQ (2, node.ledger.cache.block_count);
ASSERT_FALSE (wallet.search_pending (wallet.wallets.tx_begin_read ()));
ASSERT_FALSE (wallet.search_receivable (wallet.wallets.tx_begin_read ()));
ASSERT_TIMELY (3s, node.balance (nano::dev::genesis->account ()) == nano::dev::constants.genesis_amount);
auto receive_hash = node.ledger.latest (node.store.tx_begin_read (), nano::dev::genesis->account ());
auto receive = node.block (receive_hash);

View file

@ -143,7 +143,7 @@ TEST (wallets, exists)
}
}
TEST (wallets, search_pending)
TEST (wallets, search_receivable)
{
for (auto search_all : { false, true })
{
@ -179,11 +179,11 @@ TEST (wallets, search_pending)
ASSERT_TRUE (node.active.empty ());
if (search_all)
{
node.wallets.search_pending_all ();
node.wallets.search_receivable_all ();
}
else
{
node.wallets.search_pending (wallet_id);
node.wallets.search_receivable (wallet_id);
}
auto election = node.active.election (send->qualified_root ());
ASSERT_NE (nullptr, election);
@ -203,11 +203,11 @@ TEST (wallets, search_pending)
ASSERT_EQ (2, node.ledger.cache.block_count);
if (search_all)
{
node.wallets.search_pending_all ();
node.wallets.search_receivable_all ();
}
else
{
node.wallets.search_pending (wallet_id);
node.wallets.search_receivable (wallet_id);
}
ASSERT_TIMELY (3s, node.balance (nano::dev::genesis->account ()) == nano::dev::constants.genesis_amount);
auto receive_hash = node.ledger.latest (node.store.tx_begin_read (), nano::dev::genesis->account ());

View file

@ -612,6 +612,7 @@ void nano::json_handler::account_info ()
bool const representative = request.get<bool> ("representative", false);
bool const weight = request.get<bool> ("weight", false);
bool const pending = request.get<bool> ("pending", false);
bool const receivable = request.get<bool> ("receivable", pending);
bool const include_confirmed = request.get<bool> ("include_confirmed", false);
auto transaction (node.store.tx_begin_read ());
auto info (account_info_impl (transaction, account));
@ -690,16 +691,17 @@ void nano::json_handler::account_info ()
auto account_weight (node.ledger.weight (account));
response_l.put ("weight", account_weight.convert_to<std::string> ());
}
if (pending)
if (receivable)
{
auto account_pending (node.ledger.account_pending (transaction, account));
response_l.put ("pending", account_pending.convert_to<std::string> ());
response_l.put ("receivable", account_pending.convert_to<std::string> ());
auto account_receivable = node.ledger.account_receivable (transaction, account);
response_l.put ("pending", account_receivable.convert_to<std::string> ());
response_l.put ("receivable", account_receivable.convert_to<std::string> ());
if (include_confirmed)
{
auto account_pending (node.ledger.account_pending (transaction, account, true));
response_l.put ("confirmed_pending", account_pending.convert_to<std::string> ());
auto account_receivable = node.ledger.account_receivable (transaction, account, true);
response_l.put ("confirmed_pending", account_receivable.convert_to<std::string> ());
response_l.put ("confirmed_receivable", account_receivable.convert_to<std::string> ());
}
}
}
@ -972,6 +974,12 @@ void nano::json_handler::accounts_frontiers ()
}
void nano::json_handler::accounts_pending ()
{
response_l.put ("deprecated", "1");
accounts_receivable ();
}
void nano::json_handler::accounts_receivable ()
{
auto count (count_optional_impl ());
auto threshold (threshold_optional_impl ());
@ -1230,6 +1238,7 @@ void nano::json_handler::blocks ()
void nano::json_handler::blocks_info ()
{
bool const pending = request.get<bool> ("pending", false);
bool const receivable = request.get<bool> ("receivable", pending);
bool const source = request.get<bool> ("source", false);
bool const json_block_l = request.get<bool> ("json_block", false);
bool const include_not_found = request.get<bool> ("include_not_found", false);
@ -1282,7 +1291,7 @@ void nano::json_handler::blocks_info ()
auto subtype (nano::state_subtype (block->sideband ().details));
entry.put ("subtype", subtype);
}
if (pending)
if (receivable)
{
bool exists (false);
auto destination (node.ledger.block_destination (transaction, *block));
@ -1291,6 +1300,7 @@ void nano::json_handler::blocks_info ()
exists = node.store.pending.exists (transaction, nano::pending_key (destination, hash));
}
entry.put ("pending", exists ? "1" : "0");
entry.put ("receivable", exists ? "1" : "0");
}
if (source)
{
@ -2664,6 +2674,7 @@ void nano::json_handler::ledger ()
bool const representative = request.get<bool> ("representative", false);
bool const weight = request.get<bool> ("weight", false);
bool const pending = request.get<bool> ("pending", false);
bool const receivable = request.get<bool> ("receivable", pending);
boost::property_tree::ptree accounts;
auto transaction (node.store.tx_begin_read ());
if (!ec && !sorting) // Simple
@ -2671,19 +2682,19 @@ void nano::json_handler::ledger ()
for (auto i (node.store.account.begin (transaction, start)), n (node.store.account.end ()); i != n && accounts.size () < count; ++i)
{
nano::account_info const & info (i->second);
if (info.modified >= modified_since && (pending || info.balance.number () >= threshold.number ()))
if (info.modified >= modified_since && (receivable || info.balance.number () >= threshold.number ()))
{
nano::account const & account (i->first);
boost::property_tree::ptree response_a;
if (pending)
if (receivable)
{
auto account_pending (node.ledger.account_pending (transaction, account));
if (info.balance.number () + account_pending < threshold.number ())
auto account_receivable = node.ledger.account_receivable (transaction, account);
if (info.balance.number () + account_receivable < threshold.number ())
{
continue;
}
response_a.put ("pending", account_pending.convert_to<std::string> ());
response_a.put ("receivable", account_pending.convert_to<std::string> ());
response_a.put ("pending", account_receivable.convert_to<std::string> ());
response_a.put ("receivable", account_receivable.convert_to<std::string> ());
}
response_a.put ("frontier", info.head.to_string ());
response_a.put ("open_block", info.open_block.to_string ());
@ -2724,19 +2735,19 @@ void nano::json_handler::ledger ()
for (auto i (ledger_l.begin ()), n (ledger_l.end ()); i != n && accounts.size () < count; ++i)
{
node.store.account.get (transaction, i->second, info);
if (pending || info.balance.number () >= threshold.number ())
if (receivable || info.balance.number () >= threshold.number ())
{
nano::account const & account (i->second);
boost::property_tree::ptree response_a;
if (pending)
if (receivable)
{
auto account_pending (node.ledger.account_pending (transaction, account));
if (info.balance.number () + account_pending < threshold.number ())
auto account_receivable = node.ledger.account_receivable (transaction, account);
if (info.balance.number () + account_receivable < threshold.number ())
{
continue;
}
response_a.put ("pending", account_pending.convert_to<std::string> ());
response_a.put ("receivable", account_pending.convert_to<std::string> ());
response_a.put ("pending", account_receivable.convert_to<std::string> ());
response_a.put ("receivable", account_receivable.convert_to<std::string> ());
}
response_a.put ("frontier", info.head.to_string ());
response_a.put ("open_block", info.open_block.to_string ());
@ -2944,6 +2955,12 @@ void nano::json_handler::peers ()
}
void nano::json_handler::pending ()
{
response_l.put ("deprecated", "1");
receivable ();
}
void nano::json_handler::receivable ()
{
auto account (account_impl ());
auto count (count_optional_impl ());
@ -3053,6 +3070,12 @@ void nano::json_handler::pending ()
}
void nano::json_handler::pending_exists ()
{
response_l.put ("deprecated", "1");
receivable_exists ();
}
void nano::json_handler::receivable_exists ()
{
auto hash (hash_impl ());
bool const include_active = request.get<bool> ("include_active", false);
@ -3605,21 +3628,33 @@ void nano::json_handler::republish ()
}
void nano::json_handler::search_pending ()
{
response_l.put ("deprecated", "1");
search_receivable ();
}
void nano::json_handler::search_receivable ()
{
auto wallet (wallet_impl ());
if (!ec)
{
auto error (wallet->search_pending (wallet->wallets.tx_begin_read ()));
auto error (wallet->search_receivable (wallet->wallets.tx_begin_read ()));
response_l.put ("started", !error);
}
response_errors ();
}
void nano::json_handler::search_pending_all ()
{
response_l.put ("deprecated", "1");
search_receivable_all ();
}
void nano::json_handler::search_receivable_all ()
{
if (!ec)
{
node.wallets.search_pending_all ();
node.wallets.search_receivable_all ();
response_l.put ("success", "");
}
response_errors ();
@ -4302,7 +4337,7 @@ void nano::json_handler::wallet_info ()
if (!ec)
{
nano::uint128_t balance (0);
nano::uint128_t pending (0);
nano::uint128_t receivable (0);
uint64_t count (0);
uint64_t block_count (0);
uint64_t cemented_block_count (0);
@ -4328,7 +4363,7 @@ void nano::json_handler::wallet_info ()
}
balance += account_info.balance.number ();
pending += node.ledger.account_pending (block_transaction, account);
receivable += node.ledger.account_receivable (block_transaction, account);
nano::key_type key_type (wallet->store.key_type (i->second));
if (key_type == nano::key_type::deterministic)
@ -4345,8 +4380,8 @@ void nano::json_handler::wallet_info ()
uint32_t deterministic_index (wallet->store.deterministic_index_get (transaction));
response_l.put ("balance", balance.convert_to<std::string> ());
response_l.put ("pending", pending.convert_to<std::string> ());
response_l.put ("receivable", pending.convert_to<std::string> ());
response_l.put ("pending", receivable.convert_to<std::string> ());
response_l.put ("receivable", receivable.convert_to<std::string> ());
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));
@ -4374,10 +4409,10 @@ void nano::json_handler::wallet_balances ()
if (balance >= threshold.number ())
{
boost::property_tree::ptree entry;
nano::uint128_t pending = node.ledger.account_pending (block_transaction, account);
nano::uint128_t receivable = node.ledger.account_receivable (block_transaction, account);
entry.put ("balance", balance.convert_to<std::string> ());
entry.put ("pending", pending.convert_to<std::string> ());
entry.put ("receivable", pending.convert_to<std::string> ());
entry.put ("pending", receivable.convert_to<std::string> ());
entry.put ("receivable", receivable.convert_to<std::string> ());
balances.push_back (std::make_pair (account.to_account (), entry));
}
}
@ -4610,6 +4645,7 @@ void nano::json_handler::wallet_ledger ()
bool const representative = request.get<bool> ("representative", false);
bool const weight = request.get<bool> ("weight", false);
bool const pending = request.get<bool> ("pending", false);
bool const receivable = request.get<bool> ("receivable", pending);
uint64_t modified_since (0);
boost::optional<std::string> modified_since_text (request.get_optional<std::string> ("modified_since"));
if (modified_since_text.is_initialized ())
@ -4648,11 +4684,11 @@ void nano::json_handler::wallet_ledger ()
auto account_weight (node.ledger.weight (account));
entry.put ("weight", account_weight.convert_to<std::string> ());
}
if (pending)
if (receivable)
{
auto account_pending (node.ledger.account_pending (block_transaction, account));
entry.put ("pending", account_pending.convert_to<std::string> ());
entry.put ("receivable", account_pending.convert_to<std::string> ());
auto account_receivable (node.ledger.account_receivable (block_transaction, account));
entry.put ("pending", account_receivable.convert_to<std::string> ());
entry.put ("receivable", account_receivable.convert_to<std::string> ());
}
accounts.push_back (std::make_pair (account.to_account (), entry));
}
@ -4678,6 +4714,12 @@ void nano::json_handler::wallet_lock ()
}
void nano::json_handler::wallet_pending ()
{
response_l.put ("deprecated", "1");
wallet_receivable ();
}
void nano::json_handler::wallet_receivable ()
{
auto wallet (wallet_impl ());
auto count (count_optional_impl ());
@ -5197,6 +5239,7 @@ ipc_json_handler_no_arg_func_map create_ipc_json_handler_no_arg_func_map ()
no_arg_funcs.emplace ("accounts_create", &nano::json_handler::accounts_create);
no_arg_funcs.emplace ("accounts_frontiers", &nano::json_handler::accounts_frontiers);
no_arg_funcs.emplace ("accounts_pending", &nano::json_handler::accounts_pending);
no_arg_funcs.emplace ("accounts_receivable", &nano::json_handler::accounts_receivable);
no_arg_funcs.emplace ("active_difficulty", &nano::json_handler::active_difficulty);
no_arg_funcs.emplace ("available_supply", &nano::json_handler::available_supply);
no_arg_funcs.emplace ("block_info", &nano::json_handler::block_info);
@ -5236,8 +5279,8 @@ ipc_json_handler_no_arg_func_map create_ipc_json_handler_no_arg_func_map ()
no_arg_funcs.emplace ("peers", &nano::json_handler::peers);
no_arg_funcs.emplace ("pending", &nano::json_handler::pending);
no_arg_funcs.emplace ("pending_exists", &nano::json_handler::pending_exists);
no_arg_funcs.emplace ("receivable", &nano::json_handler::pending);
no_arg_funcs.emplace ("receivable_exists", &nano::json_handler::pending_exists);
no_arg_funcs.emplace ("receivable", &nano::json_handler::receivable);
no_arg_funcs.emplace ("receivable_exists", &nano::json_handler::receivable_exists);
no_arg_funcs.emplace ("process", &nano::json_handler::process);
no_arg_funcs.emplace ("pruned_exists", &nano::json_handler::pruned_exists);
no_arg_funcs.emplace ("receive", &nano::json_handler::receive);
@ -5247,7 +5290,9 @@ ipc_json_handler_no_arg_func_map create_ipc_json_handler_no_arg_func_map ()
no_arg_funcs.emplace ("representatives_online", &nano::json_handler::representatives_online);
no_arg_funcs.emplace ("republish", &nano::json_handler::republish);
no_arg_funcs.emplace ("search_pending", &nano::json_handler::search_pending);
no_arg_funcs.emplace ("search_receivable", &nano::json_handler::search_receivable);
no_arg_funcs.emplace ("search_pending_all", &nano::json_handler::search_pending_all);
no_arg_funcs.emplace ("search_receivable_all", &nano::json_handler::search_receivable_all);
no_arg_funcs.emplace ("send", &nano::json_handler::send);
no_arg_funcs.emplace ("sign", &nano::json_handler::sign);
no_arg_funcs.emplace ("stats", &nano::json_handler::stats);
@ -5278,6 +5323,7 @@ ipc_json_handler_no_arg_func_map create_ipc_json_handler_no_arg_func_map ()
no_arg_funcs.emplace ("wallet_ledger", &nano::json_handler::wallet_ledger);
no_arg_funcs.emplace ("wallet_lock", &nano::json_handler::wallet_lock);
no_arg_funcs.emplace ("wallet_pending", &nano::json_handler::wallet_pending);
no_arg_funcs.emplace ("wallet_receivable", &nano::json_handler::wallet_receivable);
no_arg_funcs.emplace ("wallet_representative", &nano::json_handler::wallet_representative);
no_arg_funcs.emplace ("wallet_representative_set", &nano::json_handler::wallet_representative_set);
no_arg_funcs.emplace ("wallet_republish", &nano::json_handler::wallet_republish);

View file

@ -44,6 +44,7 @@ public:
void accounts_create ();
void accounts_frontiers ();
void accounts_pending ();
void accounts_receivable ();
void active_difficulty ();
void available_supply ();
void block_info ();
@ -86,6 +87,8 @@ public:
void peers ();
void pending ();
void pending_exists ();
void receivable ();
void receivable_exists ();
void process ();
void pruned_exists ();
void receive ();
@ -95,7 +98,9 @@ public:
void representatives_online ();
void republish ();
void search_pending ();
void search_receivable ();
void search_pending_all ();
void search_receivable_all ();
void send ();
void sign ();
void stats ();
@ -125,6 +130,7 @@ public:
void wallet_ledger ();
void wallet_lock ();
void wallet_pending ();
void wallet_receivable ();
void wallet_representative ();
void wallet_representative_set ();
void wallet_republish ();

View file

@ -649,7 +649,7 @@ void nano::node::start ()
}
if (!flags.disable_search_pending)
{
search_pending ();
search_receivable_all ();
}
if (!flags.disable_wallet_bootstrap)
{
@ -744,7 +744,7 @@ std::pair<nano::uint128_t, nano::uint128_t> nano::node::balance_pending (nano::a
std::pair<nano::uint128_t, nano::uint128_t> result;
auto const transaction (store.tx_begin_read ());
result.first = ledger.account_balance (transaction, account_a, only_confirmed_a);
result.second = ledger.account_pending (transaction, account_a, only_confirmed_a);
result.second = ledger.account_receivable (transaction, account_a, only_confirmed_a);
return result;
}
@ -899,15 +899,15 @@ void nano::node::backup_wallet ()
});
}
void nano::node::search_pending ()
void nano::node::search_receivable_all ()
{
// Reload wallets from disk
wallets.reload ();
// Search pending
wallets.search_pending_all ();
wallets.search_receivable_all ();
auto this_l (shared ());
workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.search_pending_interval, [this_l] () {
this_l->search_pending ();
this_l->search_receivable_all ();
});
}
@ -1780,6 +1780,14 @@ void nano::node::populate_backlog ()
}
}
/** Convenience function to easily return the confirmation height of an account. */
uint64_t nano::node::get_confirmation_height (nano::transaction const & transaction_a, nano::account & account_a)
{
nano::confirmation_height_info info;
store.confirmation_height.get (transaction_a, account_a, info);
return info.height;
};
nano::node_wrapper::node_wrapper (boost::filesystem::path const & path_a, boost::filesystem::path const & config_path_a, nano::node_flags const & node_flags_a) :
network_params{ nano::network_constants::active_network },
io_context (std::make_shared<boost::asio::io_context> ()),

View file

@ -122,7 +122,7 @@ public:
void ongoing_unchecked_cleanup ();
void ongoing_backlog_population ();
void backup_wallet ();
void search_pending ();
void search_receivable_all ();
void bootstrap_wallet ();
void unchecked_cleanup ();
bool collect_ledger_pruning_targets (std::deque<nano::block_hash> &, nano::account &, uint64_t const, uint64_t const, uint64_t const);
@ -152,6 +152,7 @@ public:
void set_bandwidth_params (std::size_t limit, double ratio);
std::pair<uint64_t, decltype (nano::ledger::bootstrap_weights)> get_bootstrap_weights () const;
void populate_backlog ();
uint64_t get_confirmation_height (nano::transaction const &, nano::account &);
nano::write_database_queue write_database_queue;
boost::asio::io_context & io_ctx;
boost::latch node_initialized_latch;

View file

@ -700,7 +700,7 @@ bool nano::wallet::enter_password (nano::transaction const & transaction_a, std:
{
auto this_l (shared_from_this ());
wallets.node.background ([this_l] () {
this_l->search_pending (this_l->wallets.tx_begin_read ());
this_l->search_receivable (this_l->wallets.tx_begin_read ());
});
wallets.node.logger.try_log ("Wallet unlocked");
}
@ -1164,7 +1164,7 @@ void nano::wallet::work_ensure (nano::account const & account_a, nano::root cons
});
}
bool nano::wallet::search_pending (nano::transaction const & wallet_transaction_a)
bool nano::wallet::search_receivable (nano::transaction const & wallet_transaction_a)
{
auto result (!store.valid_password (wallet_transaction_a));
if (!result)
@ -1438,17 +1438,17 @@ std::shared_ptr<nano::wallet> nano::wallets::create (nano::wallet_id const & id_
return result;
}
bool nano::wallets::search_pending (nano::wallet_id const & wallet_a)
bool nano::wallets::search_receivable (nano::wallet_id const & wallet_a)
{
auto result (false);
if (auto wallet = open (wallet_a); wallet != nullptr)
{
result = wallet->search_pending (tx_begin_read ());
result = wallet->search_receivable (tx_begin_read ());
}
return result;
}
void nano::wallets::search_pending_all ()
void nano::wallets::search_receivable_all ()
{
nano::unique_lock<nano::mutex> lk (mutex);
auto wallets_l = get_wallets ();
@ -1456,7 +1456,7 @@ void nano::wallets::search_pending_all ()
lk.unlock ();
for (auto const & [id, wallet] : wallets_l)
{
wallet->search_pending (wallet_transaction);
wallet->search_receivable (wallet_transaction);
}
}

View file

@ -150,7 +150,7 @@ public:
void work_update (nano::transaction const &, nano::account const &, nano::root const &, uint64_t);
// Schedule work generation after a few seconds
void work_ensure (nano::account const &, nano::root const &);
bool search_pending (nano::transaction const &);
bool search_receivable (nano::transaction const &);
void init_free_accounts (nano::transaction const &);
uint32_t deterministic_check (nano::transaction const & transaction_a, uint32_t index);
/** Changes the wallet seed and returns the first account */
@ -198,8 +198,8 @@ public:
~wallets ();
std::shared_ptr<nano::wallet> open (nano::wallet_id const &);
std::shared_ptr<nano::wallet> create (nano::wallet_id const &);
bool search_pending (nano::wallet_id const &);
void search_pending_all ();
bool search_receivable (nano::wallet_id const &);
void search_receivable_all ();
void destroy (nano::wallet_id const &);
void reload ();
void do_wallet_actions ();

View file

@ -267,7 +267,7 @@ void nano_qt::accounts::refresh_wallet_balance ()
{
nano::public_key const & key (i->first);
balance = balance + (this->wallet.node.ledger.account_balance (block_transaction, key));
pending = pending + (this->wallet.node.ledger.account_pending (block_transaction, key));
pending = pending + (this->wallet.node.ledger.account_receivable (block_transaction, key));
}
auto final_text (std::string ("Balance: ") + wallet.format_balance (balance));
if (!pending.is_zero ())
@ -1894,7 +1894,7 @@ nano_qt::advanced_actions::advanced_actions (nano_qt::wallet & wallet_a) :
this->wallet.pop_main_stack ();
});
QObject::connect (search_for_receivables, &QPushButton::released, [this] () {
std::thread ([this] { this->wallet.wallet_m->search_pending (this->wallet.wallet_m->wallets.tx_begin_read ()); }).detach ();
std::thread ([this] { this->wallet.wallet_m->search_receivable (this->wallet.wallet_m->wallets.tx_begin_read ()); }).detach ();
});
QObject::connect (bootstrap, &QPushButton::released, [this] () {
std::thread ([this] { this->wallet.node.bootstrap_initiator.bootstrap (); }).detach ();

View file

@ -166,7 +166,9 @@ std::unordered_set<std::string> create_rpc_control_impls ()
set.emplace ("receive_minimum");
set.emplace ("receive_minimum_set");
set.emplace ("search_pending");
set.emplace ("search_receivable");
set.emplace ("search_pending_all");
set.emplace ("search_receivable_all");
set.emplace ("send");
set.emplace ("stop");
set.emplace ("unchecked_clear");

View file

@ -1844,7 +1844,7 @@ TEST (rpc, pending)
auto block4 (system.wallet (0)->send_action (nano::dev::genesis_key.pub, key1.pub, 400));
rpc_ctx.io_scope->renew ();
ASSERT_TIMELY (10s, node->ledger.account_pending (node->store.tx_begin_read (), key1.pub) == 1000);
ASSERT_TIMELY (10s, node->ledger.account_receivable (node->store.tx_begin_read (), key1.pub) == 1000);
ASSERT_TIMELY (5s, !node->active.active (*block4));
ASSERT_TIMELY (5s, node->block_confirmed (block4->hash ()));
@ -1878,7 +1878,7 @@ TEST (rpc, receivable_offset_and_sorting)
auto block6 = system.wallet (0)->send_action (nano::dev::genesis_key.pub, key1.pub, 300);
// check that all blocks got confirmed
ASSERT_TIMELY (5s, node->ledger.account_pending (node->store.tx_begin_read (), key1.pub, true) == 1600);
ASSERT_TIMELY (5s, node->ledger.account_receivable (node->store.tx_begin_read (), key1.pub, true) == 1600);
// check confirmation height is as expected, there is no perfect clarity yet when confirmation height updates after a block get confirmed
nano::confirmation_height_info confirmation_height_info;
@ -2040,7 +2040,7 @@ TEST (rpc, pending_burn)
}
}
TEST (rpc, search_pending)
TEST (rpc, search_receivable)
{
nano::system system;
auto node = add_ipc_enabled_node (system);
@ -2054,7 +2054,7 @@ TEST (rpc, search_pending)
}
auto const rpc_ctx = add_rpc (system, node);
boost::property_tree::ptree request;
request.put ("action", "search_pending");
request.put ("action", "search_receivable");
request.put ("wallet", wallet);
auto response (wait_response (system, rpc_ctx, request));
ASSERT_TIMELY (10s, node->balance (nano::dev::genesis_key.pub) == nano::dev::constants.genesis_amount);
@ -3183,6 +3183,22 @@ TEST (rpc, accounts_frontiers)
}
TEST (rpc, accounts_pending)
{
nano::system system;
auto node = add_ipc_enabled_node (system);
auto const rpc_ctx = add_rpc (system, node);
boost::property_tree::ptree request;
boost::property_tree::ptree child;
boost::property_tree::ptree accounts;
child.put ("", nano::dev::genesis_key.pub.to_account ());
accounts.push_back (std::make_pair ("", child));
request.add_child ("accounts", accounts);
request.put ("action", "accounts_pending");
auto response (wait_response (system, rpc_ctx, request));
ASSERT_EQ ("1", response.get<std::string> ("deprecated"));
}
TEST (rpc, accounts_receivable)
{
nano::system system;
auto node = add_ipc_enabled_node (system);
@ -3195,7 +3211,7 @@ TEST (rpc, accounts_pending)
auto const rpc_ctx = add_rpc (system, node);
boost::property_tree::ptree request;
request.put ("action", "accounts_pending");
request.put ("action", "accounts_receivable");
boost::property_tree::ptree entry;
boost::property_tree::ptree peers_l;
entry.put ("", key1.pub.to_account ());
@ -3430,6 +3446,28 @@ TEST (rpc, pending_exists)
}
TEST (rpc, wallet_pending)
{
nano::system system;
auto node = add_ipc_enabled_node (system);
nano::keypair key1;
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
system.wallet (0)->insert_adhoc (key1.prv);
auto block1 = system.wallet (0)->send_action (nano::dev::genesis_key.pub, key1.pub, 100);
ASSERT_TIMELY (5s, node->get_confirmation_height (node->store.tx_begin_read (), nano::dev::genesis_key.pub) == 2);
auto const rpc_ctx = add_rpc (system, node);
boost::property_tree::ptree request;
request.put ("action", "wallet_pending");
request.put ("wallet", node->wallets.items.begin ()->first.to_string ());
auto response (wait_response (system, rpc_ctx, request));
ASSERT_EQ ("1", response.get<std::string> ("deprecated"));
ASSERT_EQ (1, response.get_child ("blocks").size ());
auto pending = response.get_child ("blocks").front ();
ASSERT_EQ (key1.pub.to_account (), pending.first);
nano::block_hash hash1{ pending.second.begin ()->second.get<std::string> ("") };
ASSERT_EQ (block1->hash (), hash1);
}
TEST (rpc, wallet_receivable)
{
nano::system system0;
auto node = add_ipc_enabled_node (system0);
@ -3448,7 +3486,7 @@ TEST (rpc, wallet_pending)
auto const rpc_ctx = add_rpc (system0, node);
boost::property_tree::ptree request;
request.put ("action", "wallet_pending");
request.put ("action", "wallet_receivable");
request.put ("wallet", node->wallets.items.begin ()->first.to_string ());
request.put ("count", "100");
auto response (wait_response (system0, rpc_ctx, request));
@ -3609,7 +3647,7 @@ TEST (rpc, work_set)
ASSERT_EQ (work1, work0);
}
TEST (rpc, search_pending_all)
TEST (rpc, search_receivable_all)
{
nano::system system;
auto node = add_ipc_enabled_node (system);
@ -3622,7 +3660,7 @@ TEST (rpc, search_pending_all)
}
auto const rpc_ctx = add_rpc (system, node);
boost::property_tree::ptree request;
request.put ("action", "search_pending_all");
request.put ("action", "search_receivable_all");
auto response (wait_response (system, rpc_ctx, request));
ASSERT_TIMELY (10s, node->balance (nano::dev::genesis_key.pub) == nano::dev::constants.genesis_amount);
}
@ -3860,22 +3898,20 @@ TEST (rpc, account_info)
ASSERT_EQ (0, response.get<uint8_t> ("account_version"));
boost::optional<std::string> weight (response.get_optional<std::string> ("weight"));
ASSERT_FALSE (weight.is_initialized ());
boost::optional<std::string> pending (response.get_optional<std::string> ("pending"));
ASSERT_FALSE (pending.is_initialized ());
boost::optional<std::string> receivable (response.get_optional<std::string> ("receivable"));
ASSERT_FALSE (receivable.is_initialized ());
boost::optional<std::string> representative (response.get_optional<std::string> ("representative"));
ASSERT_FALSE (representative.is_initialized ());
}
// Test for optional values
request.put ("weight", "true");
request.put ("pending", "1");
request.put ("receivable", "1");
request.put ("representative", "1");
{
auto response (wait_response (system, rpc_ctx, request));
std::string weight2 (response.get<std::string> ("weight"));
ASSERT_EQ ("100", weight2);
std::string pending2 (response.get<std::string> ("pending"));
ASSERT_EQ ("0", pending2);
ASSERT_EQ ("100", response.get<std::string> ("weight"));
ASSERT_EQ ("0", response.get<std::string> ("receivable"));
std::string representative2 (response.get<std::string> ("representative"));
ASSERT_EQ (nano::dev::genesis_key.pub.to_account (), representative2);
}
@ -3929,24 +3965,21 @@ TEST (rpc, account_info)
request.put ("account", key1.pub.to_account ());
{
auto response (wait_response (system, rpc_ctx, request));
std::string pending (response.get<std::string> ("pending"));
ASSERT_EQ ("25", pending);
std::string confirmed_pending (response.get<std::string> ("confirmed_pending"));
ASSERT_EQ ("0", confirmed_pending);
ASSERT_EQ ("25", response.get<std::string> ("receivable"));
ASSERT_EQ ("0", response.get<std::string> ("confirmed_receivable"));
}
request.put ("include_confirmed", false);
{
auto response (wait_response (system, rpc_ctx, request));
std::string pending (response.get<std::string> ("pending"));
ASSERT_EQ ("25", pending);
ASSERT_EQ ("25", response.get<std::string> ("receivable"));
// These fields shouldn't exist
auto confirmed_balance (response.get_optional<std::string> ("confirmed_balance"));
ASSERT_FALSE (confirmed_balance.is_initialized ());
auto confirmed_pending (response.get_optional<std::string> ("confirmed_pending"));
ASSERT_FALSE (confirmed_pending.is_initialized ());
auto confirmed_receivable (response.get_optional<std::string> ("confirmed_receivable"));
ASSERT_FALSE (confirmed_receivable.is_initialized ());
auto confirmed_representative (response.get_optional<std::string> ("confirmed_representative"));
ASSERT_FALSE (confirmed_representative.is_initialized ());
@ -4027,8 +4060,8 @@ TEST (rpc, blocks_info)
ASSERT_EQ (nano::dev::constants.genesis_amount.convert_to<std::string> (), amount_text);
std::string blocks_text (blocks.second.get<std::string> ("contents"));
ASSERT_FALSE (blocks_text.empty ());
boost::optional<std::string> pending (blocks.second.get_optional<std::string> ("pending"));
ASSERT_FALSE (pending.is_initialized ());
boost::optional<std::string> receivable (blocks.second.get_optional<std::string> ("receivable"));
ASSERT_FALSE (receivable.is_initialized ());
boost::optional<std::string> source (blocks.second.get_optional<std::string> ("source_account"));
ASSERT_FALSE (source.is_initialized ());
std::string balance_text (blocks.second.get<std::string> ("balance"));
@ -4067,15 +4100,13 @@ TEST (rpc, blocks_info)
ASSERT_EQ (random_hash, blocks_not_found.begin ()->second.get<std::string> (""));
}
request.put ("source", "true");
request.put ("pending", "1");
request.put ("receivable", "1");
{
auto response (wait_response (system, rpc_ctx, request));
for (auto & blocks : response.get_child ("blocks"))
{
std::string source (blocks.second.get<std::string> ("source_account"));
ASSERT_EQ ("0", source);
std::string pending (blocks.second.get<std::string> ("pending"));
ASSERT_EQ ("0", pending);
ASSERT_EQ ("0", blocks.second.get<std::string> ("source_account"));
ASSERT_EQ ("0", blocks.second.get<std::string> ("receivable"));
}
}
}

View file

@ -839,7 +839,7 @@ nano::uint128_t nano::ledger::account_balance (nano::transaction const & transac
return result;
}
nano::uint128_t nano::ledger::account_pending (nano::transaction const & transaction_a, nano::account const & account_a, bool only_confirmed_a)
nano::uint128_t nano::ledger::account_receivable (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);

View file

@ -36,7 +36,7 @@ public:
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 &, bool = false);
nano::uint128_t account_pending (nano::transaction const &, nano::account const &, bool = false);
nano::uint128_t account_receivable (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 &);