From 53cf1be9ed7ec0cf4b3e504d3aaf99180932575d Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Mon, 11 May 2020 17:54:33 +0300 Subject: [PATCH] Fix previous balance in active_transaction::insert () (#2767) preventing possible segfault --- nano/node/active_transactions.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 2be8c2add..b1315573b 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -94,7 +94,8 @@ void nano::active_transactions::confirm_prioritized_frontiers (nano::transaction if (info.block_count > confirmation_height_info.height) { auto block (this->node.store.block_get (transaction_a, info.head)); - auto insert_result = this->insert (block); + auto previous_balance (this->node.ledger.balance (transaction_a, block->previous ())); + auto insert_result = this->insert (block, previous_balance); if (insert_result.inserted) { insert_result.election->transition_active (); @@ -511,9 +512,16 @@ nano::election_insertion_result nano::active_transactions::insert_impl (std::sha result.inserted = true; auto hash (block_a->hash ()); auto epoch (block_a->sideband ().details.epoch); - auto previous_balance = block_a->previous ().is_zero () ? 0 : previous_balance_a.value_or_eval ([& node = node, &block_a] { - return node.ledger.balance (node.store.tx_begin_read (), block_a->previous ()); - }); + nano::uint128_t previous_balance (previous_balance_a.value_or (0)); + debug_assert (!(previous_balance_a.value_or (0) > 0 && block_a->previous ().is_zero ())); + if (!previous_balance_a.is_initialized () && !block_a->previous ().is_zero ()) + { + auto transaction (node.store.tx_begin_read ()); + if (node.ledger.block_exists (block_a->previous ())) + { + previous_balance = node.ledger.balance (transaction, block_a->previous ()); + } + } double multiplier (normalized_multiplier (*block_a)); bool prioritized = roots.size () < prioritized_cutoff || multiplier > last_prioritized_multiplier.value_or (0); result.election = nano::make_shared (node, block_a, confirmation_action_a, prioritized);