diff --git a/nano/nano_node/entry.cpp b/nano/nano_node/entry.cpp index 2e8790384a..affaf01c69 100644 --- a/nano/nano_node/entry.cpp +++ b/nano/nano_node/entry.cpp @@ -98,6 +98,7 @@ int main (int argc, char * const * argv) ("debug_cemented_block_count", "Displays the number of cemented (confirmed) blocks") ("debug_stacktrace", "Display an example stacktrace") ("debug_account_versions", "Display the total counts of each version for all accounts (including unpocketed)") + ("debug_unconfirmed_frontiers", "Displays the account, height (sorted), frontier and cemented frontier for all accounts which are not fully confirmed") ("validate_blocks,debug_validate_blocks", "Check all blocks for correct hash, signature, work value") ("platform", boost::program_options::value (), "Defines the for OpenCL commands") ("device", boost::program_options::value (), "Defines for OpenCL command") @@ -1934,6 +1935,22 @@ int main (int argc, char * const * argv) output_account_version_number (i, unopened_account_version_totals[i]); } } + else if (vm.count ("debug_unconfirmed_frontiers")) + { + auto inactive_node = nano::default_inactive_node (data_path, vm); + auto node = inactive_node->node; + + auto unconfirmed_frontiers = node->ledger.unconfirmed_frontiers (); + std::cout << "Account: Height delta | Frontier | Confirmed frontier\n"; + for (auto & unconfirmed_frontier : unconfirmed_frontiers) + { + auto const & unconfirmed_info = unconfirmed_frontier.second; + + std::cout << (boost::format ("%1%: %2% %3% %4%\n") % unconfirmed_info.account.to_account () % unconfirmed_frontier.first % unconfirmed_info.frontier.to_string () % unconfirmed_info.cemented_frontier.to_string ()).str (); + } + + std::cout << "\nNumber of unconfirmed frontiers: " << unconfirmed_frontiers.size () << std::endl; + } else if (vm.count ("version")) { std::cout << "Version " << NANO_VERSION_STRING << "\n" diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index da80730b4d..f98c508de8 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -1202,6 +1202,48 @@ bool nano::ledger::block_confirmed (nano::transaction const & transaction_a, nan return confirmed; } +std::multimap> nano::ledger::unconfirmed_frontiers () const +{ + std::multimap> unconfirmed_frontiers_l; + auto transaction (store.tx_begin_read ()); + auto conf_height_i = store.confirmation_height_begin (transaction); + + for (auto i (store.latest_begin (transaction)), n (store.latest_end ()); i != n; ++i) + { + // If the confirmation height of an account doesn't exist the iterator will point 1 past it. + auto conf_height_info = conf_height_i->second; + auto const & account (i->first); + auto conf_height_exists = (conf_height_i->first == account); + if (!conf_height_exists) + { + conf_height_info.height = 0; + conf_height_info.frontier = 0; + } + + auto const & account_info (i->second); + if (account_info.block_count != conf_height_info.height) + { + // Always output as no confirmation height has been set on the account yet + auto height_delta = account_info.block_count - conf_height_info.height; + auto const & frontier = account_info.head; + auto const & cemented_frontier = conf_height_info.frontier; + unconfirmed_frontiers_l.emplace (std::piecewise_construct, std::forward_as_tuple (height_delta), std::forward_as_tuple (cemented_frontier, frontier, i->first)); + } + + if (conf_height_exists) + { + // Increment the iterator so that it stays in sync with accounts in the account table. + ++conf_height_i; + } + } + return unconfirmed_frontiers_l; +} + +nano::uncemented_info::uncemented_info (nano::block_hash const & cemented_frontier, nano::block_hash const & frontier, nano::account const & account) : +cemented_frontier (cemented_frontier), frontier (frontier), account (account) +{ +} + std::unique_ptr nano::collect_container_info (ledger & ledger, const std::string & name) { auto count = ledger.bootstrap_weights_size.load (); diff --git a/nano/secure/ledger.hpp b/nano/secure/ledger.hpp index ed1fe4cf2a..79cb7157d7 100644 --- a/nano/secure/ledger.hpp +++ b/nano/secure/ledger.hpp @@ -12,6 +12,16 @@ class stat; class write_transaction; using tally_t = std::map, std::greater>; + +class uncemented_info +{ +public: + uncemented_info (nano::block_hash const & cemented_frontier, nano::block_hash const & frontier, nano::account const & account); + nano::block_hash cemented_frontier; + nano::block_hash frontier; + nano::account account; +}; + class ledger final { public: @@ -47,6 +57,7 @@ class ledger final std::array dependent_blocks (nano::transaction const &, nano::block const &) const; nano::account const & epoch_signer (nano::link const &) const; nano::link const & epoch_link (nano::epoch) const; + std::multimap> unconfirmed_frontiers () const; static nano::uint128_t const unit; nano::network_params network_params; nano::block_store & store;