Add function ledger::account_info which encapsulates direct calls to store.account.get. Rather than directly accessing the block store, users should use the ledger interface to query for this information.

This commit is contained in:
clemahieu 2023-01-26 17:43:42 +00:00
commit 6b41733dd0
14 changed files with 123 additions and 131 deletions

View file

@ -353,9 +353,8 @@ void nano::bulk_pull_server::set_current_end ()
} }
else else
{ {
nano::account_info info; auto info = connection->node->ledger.account_info (transaction, request->start.as_account ());
auto no_address (connection->node->store.account.get (transaction, request->start.as_account (), info)); if (!info)
if (no_address)
{ {
if (connection->node->config.logging.bulk_pull_logging ()) if (connection->node->config.logging.bulk_pull_logging ())
{ {
@ -365,7 +364,7 @@ void nano::bulk_pull_server::set_current_end ()
} }
else else
{ {
current = ascending () ? info.open_block : info.head; current = ascending () ? info->open_block : info->head;
if (!request->end.is_zero ()) if (!request->end.is_zero ())
{ {
auto account (connection->node->ledger.account (transaction, request->end)); auto account (connection->node->ledger.account (transaction, request->end));

View file

@ -184,7 +184,7 @@ nano::asc_pull_ack nano::bootstrap_server::process (nano::transaction const & tr
break; break;
case asc_pull_req::hash_type::account: case asc_pull_req::hash_type::account:
{ {
auto info = store.account.get (transaction, request.start.as_account ()); auto info = ledger.account_info (transaction, request.start.as_account ());
if (info) if (info)
{ {
// Start from open block if pulling by account // Start from open block if pulling by account
@ -278,7 +278,7 @@ nano::asc_pull_ack nano::bootstrap_server::process (const nano::transaction & tr
nano::asc_pull_ack::account_info_payload response_payload{}; nano::asc_pull_ack::account_info_payload response_payload{};
response_payload.account = target; response_payload.account = target;
auto account_info = store.account.get (transaction, target); auto account_info = ledger.account_info (transaction, target);
if (account_info) if (account_info)
{ {
response_payload.account_open = account_info->open_block; response_payload.account_open = account_info->open_block;

View file

@ -237,9 +237,9 @@ nano::block_hash nano::confirmation_height_bounded::get_least_unconfirmed_hash_f
else else
{ {
// No blocks have been confirmed, so the first block will be the open block // No blocks have been confirmed, so the first block will be the open block
nano::account_info account_info; auto info = ledger.account_info (transaction_a, account_a);
release_assert (!ledger.store.account.get (transaction_a, account_a, account_info)); release_assert (info);
least_unconfirmed_hash = account_info.open_block; least_unconfirmed_hash = info->open_block;
block_height_a = 1; block_height_a = 1;
} }
return least_unconfirmed_hash; return least_unconfirmed_hash;

View file

@ -24,15 +24,15 @@ void nano::election_scheduler::manual (std::shared_ptr<nano::block> const & bloc
bool nano::election_scheduler::activate (nano::account const & account_a, nano::transaction const & transaction) bool nano::election_scheduler::activate (nano::account const & account_a, nano::transaction const & transaction)
{ {
debug_assert (!account_a.is_zero ()); debug_assert (!account_a.is_zero ());
nano::account_info account_info; auto info = node.ledger.account_info (transaction, account_a);
if (!node.store.account.get (transaction, account_a, account_info)) if (info)
{ {
nano::confirmation_height_info conf_info; nano::confirmation_height_info conf_info;
node.store.confirmation_height.get (transaction, account_a, conf_info); node.store.confirmation_height.get (transaction, account_a, conf_info);
if (conf_info.height < account_info.block_count) if (conf_info.height < info->block_count)
{ {
debug_assert (conf_info.frontier != account_info.head); debug_assert (conf_info.frontier != info->head);
auto hash = conf_info.height == 0 ? account_info.open_block : node.store.block.successor (transaction, conf_info.frontier); auto hash = conf_info.height == 0 ? info->open_block : node.store.block.successor (transaction, conf_info.frontier);
auto block = node.store.block.get (transaction, hash); auto block = node.store.block.get (transaction, hash);
debug_assert (block != nullptr); debug_assert (block != nullptr);
if (node.ledger.dependents_confirmed (transaction, *block)) if (node.ledger.dependents_confirmed (transaction, *block))
@ -40,7 +40,7 @@ bool nano::election_scheduler::activate (nano::account const & account_a, nano::
auto balance = node.ledger.balance (transaction, hash); auto balance = node.ledger.balance (transaction, hash);
auto previous_balance = node.ledger.balance (transaction, conf_info.frontier); auto previous_balance = node.ledger.balance (transaction, conf_info.frontier);
nano::lock_guard<nano::mutex> lock{ mutex }; nano::lock_guard<nano::mutex> lock{ mutex };
priority.push (account_info.modified, block, std::max (balance, previous_balance)); priority.push (info->modified, block, std::max (balance, previous_balance));
notify (); notify ();
return true; // Activated return true; // Activated
} }

View file

@ -128,18 +128,18 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc
for (auto i (accounts_list.get<modified_tag> ().begin ()), n (accounts_list.get<modified_tag> ().end ()); i != n && attempts < upgrade_batch_size && attempts < count_limit && !stopped; ++i) for (auto i (accounts_list.get<modified_tag> ().begin ()), n (accounts_list.get<modified_tag> ().end ()); i != n && attempts < upgrade_batch_size && attempts < count_limit && !stopped; ++i)
{ {
auto transaction (store.tx_begin_read ()); auto transaction (store.tx_begin_read ());
nano::account_info info;
nano::account const & account (i->account); nano::account const & account (i->account);
if (!store.account.get (transaction, account, info) && info.epoch () < epoch_a) auto info = ledger.account_info (transaction, account);
if (info && info->epoch () < epoch_a)
{ {
++attempts; ++attempts;
auto difficulty (node.network_params.work.threshold (nano::work_version::work_1, nano::block_details (epoch_a, false, false, true))); auto difficulty (node.network_params.work.threshold (nano::work_version::work_1, nano::block_details (epoch_a, false, false, true)));
nano::root const & root (info.head); nano::root const & root (info->head);
std::shared_ptr<nano::block> epoch = builder.state () std::shared_ptr<nano::block> epoch = builder.state ()
.account (account) .account (account)
.previous (info.head) .previous (info->head)
.representative (info.representative) .representative (info->representative)
.balance (info.balance) .balance (info->balance)
.link (link) .link (link)
.sign (raw_key, signer) .sign (raw_key, signer)
.work (0) .work (0)

View file

@ -261,11 +261,16 @@ nano::account_info nano::json_handler::account_info_impl (nano::transaction cons
nano::account_info result; nano::account_info result;
if (!ec) if (!ec)
{ {
if (node.store.account.get (transaction_a, account_a, result)) auto info = node.ledger.account_info (transaction_a, account_a);
if (!info)
{ {
ec = nano::error_common::account_not_found; ec = nano::error_common::account_not_found;
node.bootstrap_initiator.bootstrap_lazy (account_a, false, account_a.to_account ()); node.bootstrap_initiator.bootstrap_lazy (account_a, false, account_a.to_account ());
} }
else
{
result = *info;
}
} }
return result; return result;
} }
@ -3377,14 +3382,14 @@ void nano::json_handler::receive ()
auto work (work_optional_impl ()); auto work (work_optional_impl ());
if (!ec && work) if (!ec && work)
{ {
nano::account_info info;
nano::root head; nano::root head;
nano::epoch epoch = pending_info.epoch; nano::epoch epoch = pending_info.epoch;
if (!node.store.account.get (block_transaction, account, info)) auto info = node.ledger.account_info (block_transaction, account);
if (info)
{ {
head = info.head; head = info->head;
// When receiving, epoch version is the higher between the previous and the source blocks // When receiving, epoch version is the higher between the previous and the source blocks
epoch = std::max (info.epoch (), epoch); epoch = std::max (info->epoch (), epoch);
} }
else else
{ {

View file

@ -783,11 +783,11 @@ nano::uint128_t nano::node::weight (nano::account const & account_a)
nano::block_hash nano::node::rep_block (nano::account const & account_a) nano::block_hash nano::node::rep_block (nano::account const & account_a)
{ {
auto const transaction (store.tx_begin_read ()); auto const transaction (store.tx_begin_read ());
nano::account_info info;
nano::block_hash result (0); nano::block_hash result (0);
if (!store.account.get (transaction, account_a, info)) auto info = ledger.account_info (transaction, account_a);
if (info)
{ {
result = ledger.representative (transaction, info.head); result = ledger.representative (transaction, info->head);
} }
return result; return result;
} }

View file

@ -242,11 +242,10 @@ std::pair<std::vector<std::shared_ptr<nano::block>>, std::vector<std::shared_ptr
// Search for account root // Search for account root
if (successor.is_zero ()) if (successor.is_zero ())
{ {
nano::account_info info; auto info = ledger.account_info (transaction, root.as_account ());
auto error (ledger.store.account.get (transaction, root.as_account (), info)); if (info)
if (!error)
{ {
successor = info.open_block; successor = info->open_block;
} }
} }
if (!successor.is_zero ()) if (!successor.is_zero ())

View file

@ -849,12 +849,11 @@ std::shared_ptr<nano::block> nano::wallet::receive_action (nano::block_hash cons
{ {
store.work_get (transaction, account_a, work_a); store.work_get (transaction, account_a, work_a);
} }
nano::account_info info; auto info = wallets.node.ledger.account_info (block_transaction, account_a);
auto new_account (wallets.node.ledger.store.account.get (block_transaction, account_a, info)); if (info)
if (!new_account)
{ {
block = std::make_shared<nano::state_block> (account_a, info.head, info.representative, info.balance.number () + pending_info.amount.number (), send_hash_a, prv, account_a, work_a); block = std::make_shared<nano::state_block> (account_a, info->head, info->representative, info->balance.number () + pending_info.amount.number (), send_hash_a, prv, account_a, work_a);
details.epoch = std::max (info.epoch (), pending_info.epoch); details.epoch = std::max (info->epoch (), pending_info.epoch);
} }
else else
{ {
@ -905,10 +904,8 @@ std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const &
auto existing (store.find (transaction, source_a)); auto existing (store.find (transaction, source_a));
if (existing != store.end () && !wallets.node.ledger.latest (block_transaction, source_a).is_zero ()) if (existing != store.end () && !wallets.node.ledger.latest (block_transaction, source_a).is_zero ())
{ {
nano::account_info info; auto info = wallets.node.ledger.account_info (block_transaction, source_a);
auto error1 (wallets.node.ledger.store.account.get (block_transaction, source_a, info)); debug_assert (info);
(void)error1;
debug_assert (!error1);
nano::raw_key prv; nano::raw_key prv;
auto error2 (store.fetch (transaction, source_a, prv)); auto error2 (store.fetch (transaction, source_a, prv));
(void)error2; (void)error2;
@ -917,8 +914,8 @@ std::shared_ptr<nano::block> nano::wallet::change_action (nano::account const &
{ {
store.work_get (transaction, source_a, work_a); store.work_get (transaction, source_a, work_a);
} }
block = std::make_shared<nano::state_block> (source_a, info.head, representative_a, info.balance, 0, prv, source_a, work_a); block = std::make_shared<nano::state_block> (source_a, info->head, representative_a, info->balance, 0, prv, source_a, work_a);
details.epoch = info.epoch (); details.epoch = info->epoch ();
} }
} }
} }
@ -977,10 +974,8 @@ std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & so
auto balance (wallets.node.ledger.account_balance (block_transaction, source_a)); auto balance (wallets.node.ledger.account_balance (block_transaction, source_a));
if (!balance.is_zero () && balance >= amount_a) if (!balance.is_zero () && balance >= amount_a)
{ {
nano::account_info info; auto info = wallets.node.ledger.account_info (block_transaction, source_a);
auto error1 (wallets.node.ledger.store.account.get (block_transaction, source_a, info)); debug_assert (info);
(void)error1;
debug_assert (!error1);
nano::raw_key prv; nano::raw_key prv;
auto error2 (store.fetch (transaction, source_a, prv)); auto error2 (store.fetch (transaction, source_a, prv));
(void)error2; (void)error2;
@ -989,8 +984,8 @@ std::shared_ptr<nano::block> nano::wallet::send_action (nano::account const & so
{ {
store.work_get (transaction, source_a, work_a); store.work_get (transaction, source_a, work_a);
} }
block = std::make_shared<nano::state_block> (source_a, info.head, info.representative, balance - amount_a, account_a, prv, source_a, work_a); block = std::make_shared<nano::state_block> (source_a, info->head, info->representative, balance - amount_a, account_a, prv, source_a, work_a);
details.epoch = info.epoch (); details.epoch = info->epoch ();
if (id_mdb_val && block != nullptr) if (id_mdb_val && block != nullptr)
{ {
auto status (mdb_put (wallets.env.tx (transaction), wallets.node.wallets.send_action_ids, *id_mdb_val, nano::mdb_val (block->hash ()), 0)); auto status (mdb_put (wallets.env.tx (transaction), wallets.node.wallets.send_action_ids, *id_mdb_val, nano::mdb_val (block->hash ()), 0));

View file

@ -730,10 +730,10 @@ TEST (rpc, wallet_representative_set_force)
while (representative != key.pub) while (representative != key.pub)
{ {
auto transaction (node->store.tx_begin_read ()); auto transaction (node->store.tx_begin_read ());
nano::account_info info; auto info = node->ledger.account_info (transaction, nano::dev::genesis_key.pub);
if (!node->store.account.get (transaction, nano::dev::genesis_key.pub, info)) if (info)
{ {
representative = info.representative; representative = info->representative;
} }
ASSERT_NO_ERROR (system.poll ()); ASSERT_NO_ERROR (system.poll ());
} }

View file

@ -34,13 +34,12 @@ public:
} }
if (!error) if (!error)
{ {
nano::account_info info; auto info = ledger.account_info (transaction, pending.source);
[[maybe_unused]] auto error (ledger.store.account.get (transaction, pending.source, info)); debug_assert (info);
debug_assert (!error);
ledger.store.pending.del (transaction, key); ledger.store.pending.del (transaction, key);
ledger.cache.rep_weights.representation_add (info.representative, pending.amount.number ()); ledger.cache.rep_weights.representation_add (info->representative, pending.amount.number ());
nano::account_info new_info (block_a.hashables.previous, info.representative, info.open_block, ledger.balance (transaction, block_a.hashables.previous), nano::seconds_since_epoch (), info.block_count - 1, nano::epoch::epoch_0); nano::account_info new_info (block_a.hashables.previous, info->representative, info->open_block, ledger.balance (transaction, block_a.hashables.previous), nano::seconds_since_epoch (), info->block_count - 1, nano::epoch::epoch_0);
ledger.update_account (transaction, pending.source, info, new_info); ledger.update_account (transaction, pending.source, *info, new_info);
ledger.store.block.del (transaction, hash); ledger.store.block.del (transaction, hash);
ledger.store.frontier.del (transaction, hash); ledger.store.frontier.del (transaction, hash);
ledger.store.frontier.put (transaction, block_a.hashables.previous, pending.source); ledger.store.frontier.put (transaction, block_a.hashables.previous, pending.source);
@ -56,12 +55,11 @@ public:
// Pending account entry can be incorrect if source block was pruned. But it's not affecting correct ledger processing // Pending account entry can be incorrect if source block was pruned. But it's not affecting correct ledger processing
[[maybe_unused]] bool is_pruned (false); [[maybe_unused]] bool is_pruned (false);
auto source_account (ledger.account_safe (transaction, block_a.hashables.source, is_pruned)); auto source_account (ledger.account_safe (transaction, block_a.hashables.source, is_pruned));
nano::account_info info; auto info = ledger.account_info (transaction, destination_account);
[[maybe_unused]] auto error (ledger.store.account.get (transaction, destination_account, info)); debug_assert (info);
debug_assert (!error); ledger.cache.rep_weights.representation_add (info->representative, 0 - amount);
ledger.cache.rep_weights.representation_add (info.representative, 0 - amount); nano::account_info new_info (block_a.hashables.previous, info->representative, info->open_block, ledger.balance (transaction, block_a.hashables.previous), nano::seconds_since_epoch (), info->block_count - 1, nano::epoch::epoch_0);
nano::account_info new_info (block_a.hashables.previous, info.representative, info.open_block, ledger.balance (transaction, block_a.hashables.previous), nano::seconds_since_epoch (), info.block_count - 1, nano::epoch::epoch_0); ledger.update_account (transaction, destination_account, *info, new_info);
ledger.update_account (transaction, destination_account, info, new_info);
ledger.store.block.del (transaction, hash); ledger.store.block.del (transaction, hash);
ledger.store.pending.put (transaction, nano::pending_key (destination_account, block_a.hashables.source), { source_account, amount, nano::epoch::epoch_0 }); ledger.store.pending.put (transaction, nano::pending_key (destination_account, block_a.hashables.source), { source_account, amount, nano::epoch::epoch_0 });
ledger.store.frontier.del (transaction, hash); ledger.store.frontier.del (transaction, hash);
@ -90,17 +88,16 @@ public:
auto hash (block_a.hash ()); auto hash (block_a.hash ());
auto rep_block (ledger.representative (transaction, block_a.hashables.previous)); auto rep_block (ledger.representative (transaction, block_a.hashables.previous));
auto account (ledger.account (transaction, block_a.hashables.previous)); auto account (ledger.account (transaction, block_a.hashables.previous));
nano::account_info info; auto info = ledger.account_info (transaction, account);
[[maybe_unused]] auto error (ledger.store.account.get (transaction, account, info)); debug_assert (info);
debug_assert (!error);
auto balance (ledger.balance (transaction, block_a.hashables.previous)); auto balance (ledger.balance (transaction, block_a.hashables.previous));
auto block = ledger.store.block.get (transaction, rep_block); auto block = ledger.store.block.get (transaction, rep_block);
release_assert (block != nullptr); release_assert (block != nullptr);
auto representative = block->representative (); auto representative = block->representative ();
ledger.cache.rep_weights.representation_add_dual (block_a.representative (), 0 - balance, representative, balance); ledger.cache.rep_weights.representation_add_dual (block_a.representative (), 0 - balance, representative, balance);
ledger.store.block.del (transaction, hash); ledger.store.block.del (transaction, hash);
nano::account_info new_info (block_a.hashables.previous, representative, info.open_block, info.balance, nano::seconds_since_epoch (), info.block_count - 1, nano::epoch::epoch_0); nano::account_info new_info (block_a.hashables.previous, representative, info->open_block, info->balance, nano::seconds_since_epoch (), info->block_count - 1, nano::epoch::epoch_0);
ledger.update_account (transaction, account, info, new_info); ledger.update_account (transaction, account, *info, new_info);
ledger.store.frontier.del (transaction, hash); ledger.store.frontier.del (transaction, hash);
ledger.store.frontier.put (transaction, block_a.hashables.previous, account); ledger.store.frontier.put (transaction, block_a.hashables.previous, account);
ledger.store.block.successor_clear (transaction, block_a.hashables.previous); ledger.store.block.successor_clear (transaction, block_a.hashables.previous);
@ -131,8 +128,8 @@ public:
ledger.cache.rep_weights.representation_add (block_a.representative (), 0 - block_a.hashables.balance.number ()); ledger.cache.rep_weights.representation_add (block_a.representative (), 0 - block_a.hashables.balance.number ());
} }
nano::account_info info; auto info = ledger.account_info (transaction, block_a.hashables.account);
auto error (ledger.store.account.get (transaction, block_a.hashables.account, info)); debug_assert (info);
if (is_send) if (is_send)
{ {
@ -156,8 +153,8 @@ public:
debug_assert (!error); debug_assert (!error);
auto previous_version (ledger.store.block.version (transaction, block_a.hashables.previous)); auto previous_version (ledger.store.block.version (transaction, block_a.hashables.previous));
nano::account_info new_info (block_a.hashables.previous, representative, info.open_block, balance, nano::seconds_since_epoch (), info.block_count - 1, previous_version); nano::account_info new_info (block_a.hashables.previous, representative, info->open_block, balance, nano::seconds_since_epoch (), info->block_count - 1, previous_version);
ledger.update_account (transaction, block_a.hashables.account, info, new_info); ledger.update_account (transaction, block_a.hashables.account, *info, new_info);
auto previous (ledger.store.block.get (transaction, block_a.hashables.previous)); auto previous (ledger.store.block.get (transaction, block_a.hashables.previous));
if (previous != nullptr) if (previous != nullptr)
@ -461,11 +458,9 @@ void ledger_processor::change_block (nano::change_block & block_a)
result.code = account.is_zero () ? nano::process_result::fork : nano::process_result::progress; result.code = account.is_zero () ? nano::process_result::fork : nano::process_result::progress;
if (result.code == nano::process_result::progress) if (result.code == nano::process_result::progress)
{ {
nano::account_info info; auto info = ledger.account_info (transaction, account);
auto latest_error (ledger.store.account.get (transaction, account, info)); debug_assert (info);
(void)latest_error; debug_assert (info->head == block_a.hashables.previous);
debug_assert (!latest_error);
debug_assert (info.head == block_a.hashables.previous);
result.code = validate_message (account, hash, block_a.signature) ? nano::process_result::bad_signature : nano::process_result::progress; // Is this block signed correctly (Malformed) result.code = validate_message (account, hash, block_a.signature) ? nano::process_result::bad_signature : nano::process_result::progress; // Is this block signed correctly (Malformed)
if (result.code == nano::process_result::progress) if (result.code == nano::process_result::progress)
{ {
@ -474,12 +469,12 @@ void ledger_processor::change_block (nano::change_block & block_a)
if (result.code == nano::process_result::progress) if (result.code == nano::process_result::progress)
{ {
debug_assert (!validate_message (account, hash, block_a.signature)); debug_assert (!validate_message (account, hash, block_a.signature));
block_a.sideband_set (nano::block_sideband (account, 0, info.balance, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */)); block_a.sideband_set (nano::block_sideband (account, 0, info->balance, info->block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
ledger.store.block.put (transaction, hash, block_a); ledger.store.block.put (transaction, hash, block_a);
auto balance (ledger.balance (transaction, block_a.hashables.previous)); auto balance (ledger.balance (transaction, block_a.hashables.previous));
ledger.cache.rep_weights.representation_add_dual (block_a.representative (), balance, info.representative, 0 - balance); ledger.cache.rep_weights.representation_add_dual (block_a.representative (), balance, info->representative, 0 - balance);
nano::account_info new_info (hash, block_a.representative (), info.open_block, info.balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0); nano::account_info new_info (hash, block_a.representative (), info->open_block, info->balance, nano::seconds_since_epoch (), info->block_count + 1, nano::epoch::epoch_0);
ledger.update_account (transaction, account, info, new_info); ledger.update_account (transaction, account, *info, new_info);
ledger.store.frontier.del (transaction, block_a.hashables.previous); ledger.store.frontier.del (transaction, block_a.hashables.previous);
ledger.store.frontier.put (transaction, hash, account); ledger.store.frontier.put (transaction, hash, account);
ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::change); ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::change);
@ -517,20 +512,18 @@ void ledger_processor::send_block (nano::send_block & block_a)
if (result.code == nano::process_result::progress) if (result.code == nano::process_result::progress)
{ {
debug_assert (!validate_message (account, hash, block_a.signature)); debug_assert (!validate_message (account, hash, block_a.signature));
nano::account_info info; auto info = ledger.account_info (transaction, account);
auto latest_error (ledger.store.account.get (transaction, account, info)); debug_assert (info);
(void)latest_error; debug_assert (info->head == block_a.hashables.previous);
debug_assert (!latest_error); result.code = info->balance.number () >= block_a.hashables.balance.number () ? nano::process_result::progress : nano::process_result::negative_spend; // Is this trying to spend a negative amount (Malicious)
debug_assert (info.head == block_a.hashables.previous);
result.code = info.balance.number () >= block_a.hashables.balance.number () ? nano::process_result::progress : nano::process_result::negative_spend; // Is this trying to spend a negative amount (Malicious)
if (result.code == nano::process_result::progress) if (result.code == nano::process_result::progress)
{ {
auto amount (info.balance.number () - block_a.hashables.balance.number ()); auto amount (info->balance.number () - block_a.hashables.balance.number ());
ledger.cache.rep_weights.representation_add (info.representative, 0 - amount); ledger.cache.rep_weights.representation_add (info->representative, 0 - amount);
block_a.sideband_set (nano::block_sideband (account, 0, block_a.hashables.balance /* unused */, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */)); block_a.sideband_set (nano::block_sideband (account, 0, block_a.hashables.balance /* unused */, info->block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
ledger.store.block.put (transaction, hash, block_a); ledger.store.block.put (transaction, hash, block_a);
nano::account_info new_info (hash, info.representative, info.open_block, block_a.hashables.balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0); nano::account_info new_info (hash, info->representative, info->open_block, block_a.hashables.balance, nano::seconds_since_epoch (), info->block_count + 1, nano::epoch::epoch_0);
ledger.update_account (transaction, account, info, new_info); ledger.update_account (transaction, account, *info, new_info);
ledger.store.pending.put (transaction, nano::pending_key (block_a.hashables.destination, hash), { account, amount, nano::epoch::epoch_0 }); ledger.store.pending.put (transaction, nano::pending_key (block_a.hashables.destination, hash), { account, amount, nano::epoch::epoch_0 });
ledger.store.frontier.del (transaction, block_a.hashables.previous); ledger.store.frontier.del (transaction, block_a.hashables.previous);
ledger.store.frontier.put (transaction, hash, account); ledger.store.frontier.put (transaction, hash, account);
@ -569,9 +562,9 @@ void ledger_processor::receive_block (nano::receive_block & block_a)
result.code = ledger.block_or_pruned_exists (transaction, block_a.hashables.source) ? nano::process_result::progress : nano::process_result::gap_source; // Have we seen the source block already? (Harmless) result.code = ledger.block_or_pruned_exists (transaction, block_a.hashables.source) ? nano::process_result::progress : nano::process_result::gap_source; // Have we seen the source block already? (Harmless)
if (result.code == nano::process_result::progress) if (result.code == nano::process_result::progress)
{ {
nano::account_info info; auto info = ledger.account_info (transaction, account);
ledger.store.account.get (transaction, account, info); debug_assert (info);
result.code = info.head == block_a.hashables.previous ? nano::process_result::progress : nano::process_result::gap_previous; // Block doesn't immediately follow latest block (Harmless) result.code = info->head == block_a.hashables.previous ? nano::process_result::progress : nano::process_result::gap_previous; // Block doesn't immediately follow latest block (Harmless)
if (result.code == nano::process_result::progress) if (result.code == nano::process_result::progress)
{ {
nano::pending_key key (account, block_a.hashables.source); nano::pending_key key (account, block_a.hashables.source);
@ -586,7 +579,7 @@ void ledger_processor::receive_block (nano::receive_block & block_a)
result.code = ledger.constants.work.difficulty (block_a) >= ledger.constants.work.threshold (block_a.work_version (), block_details) ? nano::process_result::progress : nano::process_result::insufficient_work; // Does this block have sufficient work? (Malformed) result.code = ledger.constants.work.difficulty (block_a) >= ledger.constants.work.threshold (block_a.work_version (), block_details) ? nano::process_result::progress : nano::process_result::insufficient_work; // Does this block have sufficient work? (Malformed)
if (result.code == nano::process_result::progress) if (result.code == nano::process_result::progress)
{ {
auto new_balance (info.balance.number () + pending.amount.number ()); auto new_balance (info->balance.number () + pending.amount.number ());
#ifdef NDEBUG #ifdef NDEBUG
if (ledger.store.block.exists (transaction, block_a.hashables.source)) if (ledger.store.block.exists (transaction, block_a.hashables.source))
{ {
@ -596,11 +589,11 @@ void ledger_processor::receive_block (nano::receive_block & block_a)
} }
#endif #endif
ledger.store.pending.del (transaction, key); ledger.store.pending.del (transaction, key);
block_a.sideband_set (nano::block_sideband (account, 0, new_balance, info.block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */)); block_a.sideband_set (nano::block_sideband (account, 0, new_balance, info->block_count + 1, nano::seconds_since_epoch (), block_details, nano::epoch::epoch_0 /* unused */));
ledger.store.block.put (transaction, hash, block_a); ledger.store.block.put (transaction, hash, block_a);
nano::account_info new_info (hash, info.representative, info.open_block, new_balance, nano::seconds_since_epoch (), info.block_count + 1, nano::epoch::epoch_0); nano::account_info new_info (hash, info->representative, info->open_block, new_balance, nano::seconds_since_epoch (), info->block_count + 1, nano::epoch::epoch_0);
ledger.update_account (transaction, account, info, new_info); ledger.update_account (transaction, account, *info, new_info);
ledger.cache.rep_weights.representation_add (info.representative, pending.amount.number ()); ledger.cache.rep_weights.representation_add (info->representative, pending.amount.number ());
ledger.store.frontier.del (transaction, block_a.hashables.previous); ledger.store.frontier.del (transaction, block_a.hashables.previous);
ledger.store.frontier.put (transaction, hash, account); ledger.store.frontier.put (transaction, hash, account);
ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::receive); ledger.stats.inc (nano::stat::type::ledger, nano::stat::detail::receive);
@ -779,11 +772,10 @@ nano::uint128_t nano::ledger::account_balance (nano::transaction const & transac
} }
else else
{ {
nano::account_info info; auto info = account_info (transaction_a, account_a);
auto none (store.account.get (transaction_a, account_a, info)); if (info)
if (!none)
{ {
result = info.balance.number (); result = info->balance.number ();
} }
} }
return result; return result;
@ -998,7 +990,6 @@ bool nano::ledger::rollback (nano::write_transaction const & transaction_a, nano
auto account_l (account (transaction_a, block_a)); auto account_l (account (transaction_a, block_a));
auto block_account_height (store.block.account_height (transaction_a, block_a)); auto block_account_height (store.block.account_height (transaction_a, block_a));
rollback_visitor rollback (transaction_a, *this, list_a); rollback_visitor rollback (transaction_a, *this, list_a);
nano::account_info account_info;
auto error (false); auto error (false);
while (!error && store.block.exists (transaction_a, block_a)) while (!error && store.block.exists (transaction_a, block_a))
{ {
@ -1006,9 +997,9 @@ bool nano::ledger::rollback (nano::write_transaction const & transaction_a, nano
store.confirmation_height.get (transaction_a, account_l, confirmation_height_info); store.confirmation_height.get (transaction_a, account_l, confirmation_height_info);
if (block_account_height > confirmation_height_info.height) if (block_account_height > confirmation_height_info.height)
{ {
auto latest_error = store.account.get (transaction_a, account_l, account_info); auto info = account_info (transaction_a, account_l);
debug_assert (!latest_error); debug_assert (info);
auto block (store.block.get (transaction_a, account_info.head)); auto block (store.block.get (transaction_a, info->head));
list_a.push_back (block); list_a.push_back (block);
block->visit (rollback); block->visit (rollback);
error = rollback.error; error = rollback.error;
@ -1070,6 +1061,11 @@ nano::account nano::ledger::account_safe (const nano::transaction & transaction,
} }
} }
std::optional<nano::account_info> nano::ledger::account_info (nano::transaction const & transaction, nano::account const & account) const
{
return store.account.get (transaction, account);
}
// Return amount decrease or increase for block // Return amount decrease or increase for block
nano::uint128_t nano::ledger::amount (nano::transaction const & transaction_a, nano::account const & account_a) nano::uint128_t nano::ledger::amount (nano::transaction const & transaction_a, nano::account const & account_a)
{ {
@ -1098,22 +1094,21 @@ nano::uint128_t nano::ledger::amount_safe (nano::transaction const & transaction
// Return latest block for account // Return latest block for account
nano::block_hash nano::ledger::latest (nano::transaction const & transaction_a, nano::account const & account_a) nano::block_hash nano::ledger::latest (nano::transaction const & transaction_a, nano::account const & account_a)
{ {
nano::account_info info; auto info = account_info (transaction_a, account_a);
auto latest_error (store.account.get (transaction_a, account_a, info)); return !info ? 0 : info->head;
return latest_error ? 0 : info.head;
} }
// Return latest root for account, account number if there are no blocks for this account. // Return latest root for account, account number if there are no blocks for this account.
nano::root nano::ledger::latest_root (nano::transaction const & transaction_a, nano::account const & account_a) nano::root nano::ledger::latest_root (nano::transaction const & transaction_a, nano::account const & account_a)
{ {
nano::account_info info; auto info = account_info (transaction_a, account_a);
if (store.account.get (transaction_a, account_a, info)) if (!info)
{ {
return account_a; return account_a;
} }
else else
{ {
return info.head; return info->head;
} }
} }
@ -1331,11 +1326,9 @@ std::shared_ptr<nano::block> nano::ledger::forked_block (nano::transaction const
auto result (store.block.get (transaction_a, store.block.successor (transaction_a, root.as_block_hash ()))); auto result (store.block.get (transaction_a, store.block.successor (transaction_a, root.as_block_hash ())));
if (result == nullptr) if (result == nullptr)
{ {
nano::account_info info; auto info = account_info (transaction_a, root.as_account ());
auto error (store.account.get (transaction_a, root.as_account (), info)); debug_assert (info);
(void)error; result = store.block.get (transaction_a, info->open_block);
debug_assert (!error);
result = store.block.get (transaction_a, info.open_block);
debug_assert (result != nullptr); debug_assert (result != nullptr);
} }
return result; return result;

View file

@ -32,6 +32,7 @@ public:
* Return account containing hash, expects that block hash exists in ledger * Return account containing hash, expects that block hash exists in ledger
*/ */
nano::account account (nano::transaction const &, nano::block_hash const &) const; nano::account account (nano::transaction const &, nano::block_hash const &) const;
std::optional<nano::account_info> account_info (nano::transaction const & transaction, nano::account const & account) const;
/** /**
* For non-prunning nodes same as `ledger::account()` * For non-prunning nodes same as `ledger::account()`
* For prunning nodes ensures that block hash exists, otherwise returns zero account * For prunning nodes ensures that block hash exists, otherwise returns zero account

View file

@ -907,17 +907,18 @@ TEST (confirmation_height, long_chains)
ASSERT_TIMELY (30s, node->ledger.block_confirmed (node->store.tx_begin_read (), receive1->hash ())); ASSERT_TIMELY (30s, node->ledger.block_confirmed (node->store.tx_begin_read (), receive1->hash ()));
auto transaction (node->store.tx_begin_read ()); auto transaction (node->store.tx_begin_read ());
nano::account_info account_info; auto info = node->ledger.account_info (transaction, nano::dev::genesis_key.pub);
ASSERT_FALSE (node->store.account.get (transaction, nano::dev::genesis_key.pub, account_info)); ASSERT_TRUE (info);
nano::confirmation_height_info confirmation_height_info; nano::confirmation_height_info confirmation_height_info;
ASSERT_FALSE (node->store.confirmation_height.get (transaction, nano::dev::genesis_key.pub, confirmation_height_info)); ASSERT_FALSE (node->store.confirmation_height.get (transaction, nano::dev::genesis_key.pub, confirmation_height_info));
ASSERT_EQ (num_blocks + 2, confirmation_height_info.height); ASSERT_EQ (num_blocks + 2, confirmation_height_info.height);
ASSERT_EQ (num_blocks + 3, account_info.block_count); // Includes the unpocketed send ASSERT_EQ (num_blocks + 3, info->block_count); // Includes the unpocketed send
ASSERT_FALSE (node->store.account.get (transaction, key1.pub, account_info)); info = node->ledger.account_info (transaction, key1.pub);
ASSERT_TRUE (info);
ASSERT_FALSE (node->store.confirmation_height.get (transaction, key1.pub, confirmation_height_info)); ASSERT_FALSE (node->store.confirmation_height.get (transaction, key1.pub, confirmation_height_info));
ASSERT_EQ (num_blocks + 1, confirmation_height_info.height); ASSERT_EQ (num_blocks + 1, confirmation_height_info.height);
ASSERT_EQ (num_blocks + 1, account_info.block_count); ASSERT_EQ (num_blocks + 1, info->block_count);
size_t cemented_count = 0; size_t cemented_count = 0;
for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end ()); i != n; ++i) for (auto i (node->ledger.store.confirmation_height.begin (transaction)), n (node->ledger.store.confirmation_height.end ()); i != n; ++i)

View file

@ -400,11 +400,10 @@ void nano::test::system::generate_rollback (nano::node & node_a, std::vector<nan
debug_assert (std::numeric_limits<CryptoPP::word32>::max () > accounts_a.size ()); debug_assert (std::numeric_limits<CryptoPP::word32>::max () > accounts_a.size ());
auto index (random_pool::generate_word32 (0, static_cast<CryptoPP::word32> (accounts_a.size () - 1))); auto index (random_pool::generate_word32 (0, static_cast<CryptoPP::word32> (accounts_a.size () - 1)));
auto account (accounts_a[index]); auto account (accounts_a[index]);
nano::account_info info; auto info = node_a.ledger.account_info (transaction, account);
auto error (node_a.store.account.get (transaction, account, info)); if (info)
if (!error)
{ {
auto hash (info.open_block); auto hash (info->open_block);
if (hash != node_a.network_params.ledger.genesis->hash ()) if (hash != node_a.network_params.ledger.genesis->hash ())
{ {
accounts_a[index] = accounts_a[accounts_a.size () - 1]; accounts_a[index] = accounts_a[accounts_a.size () - 1];