Ledger balance consistency checks
This commit is contained in:
parent
1c5e8cc16e
commit
e3d998dcda
6 changed files with 92 additions and 41 deletions
|
|
@ -1373,7 +1373,7 @@ int main (int argc, char * const * argv)
|
|||
|
||||
auto node_flags = nano::inactive_node_flag_defaults ();
|
||||
nano::update_flags (node_flags, vm);
|
||||
node_flags.generate_cache.enable_all ();
|
||||
node_flags.generate_cache = nano::generate_cache_flags::all_enabled ();
|
||||
nano::inactive_node inactive_node_l (data_path, node_flags);
|
||||
|
||||
nano::node_rpc_config config;
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ nano::node_flags const & nano::inactive_node_flag_defaults ()
|
|||
static nano::node_flags node_flags;
|
||||
node_flags.inactive_node = true;
|
||||
node_flags.read_only = true;
|
||||
node_flags.generate_cache.reps = false;
|
||||
node_flags.generate_cache.cemented_count = false;
|
||||
node_flags.generate_cache.unchecked_count = false;
|
||||
node_flags.generate_cache.account_count = false;
|
||||
node_flags.generate_cache = nano::generate_cache_flags::all_disabled ();
|
||||
node_flags.disable_bootstrap_listener = true;
|
||||
node_flags.disable_tcp_realtime = true;
|
||||
return node_flags;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ add_library(
|
|||
common.cpp
|
||||
fwd.hpp
|
||||
generate_cache_flags.hpp
|
||||
generate_cache_flags.cpp
|
||||
ledger.hpp
|
||||
ledger.cpp
|
||||
ledger_set_any.hpp
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
#include <nano/secure/generate_cache_flags.hpp>
|
||||
|
||||
void nano::generate_cache_flags::enable_all ()
|
||||
{
|
||||
reps = true;
|
||||
cemented_count = true;
|
||||
unchecked_count = true;
|
||||
account_count = true;
|
||||
}
|
||||
|
|
@ -7,24 +7,29 @@ namespace nano
|
|||
class generate_cache_flags
|
||||
{
|
||||
public:
|
||||
bool reps = true;
|
||||
bool cemented_count = true;
|
||||
bool unchecked_count = true;
|
||||
bool account_count = true;
|
||||
bool block_count = true;
|
||||
|
||||
void enable_all ();
|
||||
bool reps{ true };
|
||||
bool cemented_count{ true };
|
||||
bool unchecked_count{ true };
|
||||
bool account_count{ true };
|
||||
bool block_count{ true };
|
||||
bool consistency_check{ true };
|
||||
|
||||
public:
|
||||
static generate_cache_flags all_enabled ()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
static generate_cache_flags all_disabled ()
|
||||
{
|
||||
generate_cache_flags flags;
|
||||
flags.reps = false;
|
||||
flags.cemented_count = false;
|
||||
flags.unchecked_count = false;
|
||||
flags.account_count = false;
|
||||
flags.block_count = false;
|
||||
return flags;
|
||||
return {
|
||||
.reps = false,
|
||||
.cemented_count = false,
|
||||
.unchecked_count = false,
|
||||
.account_count = false,
|
||||
.block_count = false,
|
||||
.consistency_check = false,
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -790,6 +790,8 @@ void nano::ledger::initialize (nano::generate_cache_flags const & generate_cache
|
|||
|
||||
if (generate_cache_flags.account_count || generate_cache_flags.block_count)
|
||||
{
|
||||
logger.debug (nano::log::type::ledger, "Generating block count cache...");
|
||||
|
||||
store.account.for_each_par (
|
||||
[this] (store::read_transaction const &, auto i, auto n) {
|
||||
uint64_t block_count_l{ 0 };
|
||||
|
|
@ -803,10 +805,40 @@ void nano::ledger::initialize (nano::generate_cache_flags const & generate_cache
|
|||
this->cache.block_count += block_count_l;
|
||||
this->cache.account_count += account_count_l;
|
||||
});
|
||||
|
||||
logger.debug (nano::log::type::ledger, "Block count cache generated");
|
||||
}
|
||||
|
||||
if (generate_cache_flags.cemented_count)
|
||||
{
|
||||
logger.debug (nano::log::type::ledger, "Generating cemented count cache...");
|
||||
|
||||
store.confirmation_height.for_each_par (
|
||||
[this] (store::read_transaction const &, auto i, auto n) {
|
||||
uint64_t cemented_count_l (0);
|
||||
for (; i != n; ++i)
|
||||
{
|
||||
cemented_count_l += i->second.height;
|
||||
}
|
||||
this->cache.cemented_count += cemented_count_l;
|
||||
});
|
||||
|
||||
logger.debug (nano::log::type::ledger, "Cemented count cache generated");
|
||||
}
|
||||
|
||||
{
|
||||
logger.debug (nano::log::type::ledger, "Generating pruned count cache...");
|
||||
|
||||
auto transaction = store.tx_begin_read ();
|
||||
cache.pruned_count = store.pruned.count (transaction);
|
||||
|
||||
logger.debug (nano::log::type::ledger, "Pruned count cache generated");
|
||||
}
|
||||
|
||||
if (generate_cache_flags.reps)
|
||||
{
|
||||
logger.debug (nano::log::type::ledger, "Generating representative weights cache...");
|
||||
|
||||
store.rep_weight.for_each_par (
|
||||
[this] (store::read_transaction const &, auto i, auto n) {
|
||||
nano::rep_weights rep_weights_l{ this->store.rep_weight };
|
||||
|
|
@ -828,24 +860,50 @@ void nano::ledger::initialize (nano::generate_cache_flags const & generate_cache
|
|||
});
|
||||
|
||||
rep_weights.verify_consistency ();
|
||||
|
||||
logger.debug (nano::log::type::ledger, "Representative weights cache generated");
|
||||
}
|
||||
|
||||
if (generate_cache_flags.cemented_count)
|
||||
nano::uint128_t account_balance, pending_balance;
|
||||
|
||||
if (generate_cache_flags.consistency_check)
|
||||
{
|
||||
store.confirmation_height.for_each_par (
|
||||
[this] (store::read_transaction const &, auto i, auto n) {
|
||||
uint64_t cemented_count_l (0);
|
||||
logger.debug (nano::log::type::ledger, "Verifying ledger balance consistency...");
|
||||
|
||||
// Verify sum of all account and pending balances
|
||||
nano::locked<nano::uint128_t> accounts_balance_s{ 0 };
|
||||
nano::locked<nano::uint128_t> pending_balance_s{ 0 };
|
||||
|
||||
store.account.for_each_par (
|
||||
[&] (store::read_transaction const &, auto i, auto n) {
|
||||
nano::uint128_t balance_l{ 0 };
|
||||
for (; i != n; ++i)
|
||||
{
|
||||
cemented_count_l += i->second.height;
|
||||
nano::account_info const & info = i->second;
|
||||
balance_l += info.balance.number ();
|
||||
}
|
||||
this->cache.cemented_count += cemented_count_l;
|
||||
(*accounts_balance_s.lock ()) += balance_l;
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction (store.tx_begin_read ());
|
||||
cache.pruned_count = store.pruned.count (transaction);
|
||||
store.pending.for_each_par (
|
||||
[&] (store::read_transaction const &, auto i, auto n) {
|
||||
nano::uint128_t balance_l{ 0 };
|
||||
for (; i != n; ++i)
|
||||
{
|
||||
nano::pending_info const & info = i->second;
|
||||
balance_l += info.amount.number ();
|
||||
}
|
||||
(*pending_balance_s.lock ()) += balance_l;
|
||||
});
|
||||
|
||||
account_balance = *accounts_balance_s.lock ();
|
||||
pending_balance = *pending_balance_s.lock ();
|
||||
|
||||
release_assert (account_balance + pending_balance == constants.genesis_amount, "ledger corruption detected: account and pending balances do not match genesis amount", to_string (account_balance) + " + " + to_string (pending_balance) + " != " + to_string (constants.genesis_amount));
|
||||
release_assert (account_balance == rep_weights.get_weight_committed (), "ledger corruption detected: account balance does not match committed representative weights", to_string (account_balance) + " != " + to_string (rep_weights.get_weight_committed ()));
|
||||
release_assert (pending_balance == rep_weights.get_weight_unused (), "ledger corruption detected: pending balance does not match unused representative weights", to_string (pending_balance) + " != " + to_string (rep_weights.get_weight_unused ()));
|
||||
|
||||
logger.debug (nano::log::type::ledger, "Ledger balance consistency verified");
|
||||
}
|
||||
|
||||
logger.info (nano::log::type::ledger, "Block count: {:>11}", cache.block_count.load ());
|
||||
|
|
@ -853,6 +911,9 @@ void nano::ledger::initialize (nano::generate_cache_flags const & generate_cache
|
|||
logger.info (nano::log::type::ledger, "Account count: {:>11}", cache.account_count.load ());
|
||||
logger.info (nano::log::type::ledger, "Pruned count: {:>11}", cache.pruned_count.load ());
|
||||
logger.info (nano::log::type::ledger, "Representative count: {:>5}", rep_weights.size ());
|
||||
logger.info (nano::log::type::ledger, "Total balance: {} | pending: {}",
|
||||
nano::uint128_union{ account_balance }.format_balance (nano::nano_ratio, 0, true),
|
||||
nano::uint128_union{ pending_balance }.format_balance (nano::nano_ratio, 0, true));
|
||||
logger.info (nano::log::type::ledger, "Weight commited: {} | unused: {}",
|
||||
nano::uint128_union{ rep_weights.get_weight_committed () }.format_balance (nano::nano_ratio, 0, true),
|
||||
nano::uint128_union{ rep_weights.get_weight_unused () }.format_balance (nano::nano_ratio, 0, true));
|
||||
|
|
@ -1267,7 +1328,6 @@ std::optional<nano::account> nano::ledger::linked_account (secure::transaction c
|
|||
{
|
||||
return any.block_account (transaction, block.source ());
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
|
@ -1602,7 +1662,6 @@ nano::epoch nano::ledger::version (nano::block const & block)
|
|||
{
|
||||
return block.sideband ().details.epoch;
|
||||
}
|
||||
|
||||
return nano::epoch::epoch_0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue