From 5390459d99660a4c5da84164cabdc156d6041803 Mon Sep 17 00:00:00 2001 From: Thiago Silva Date: Wed, 10 May 2023 14:06:23 -0300 Subject: [PATCH] Fix access without lock in active_transactions::confirm_block function --- nano/node/active_transactions.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 7d0cd40b9b..4af0bfbcc7 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -610,20 +610,27 @@ bool nano::active_transactions::publish (std::shared_ptr const & bl // Returns the type of election status requiring callbacks calling later boost::optional nano::active_transactions::confirm_block (nano::transaction const & transaction_a, std::shared_ptr const & block_a) { - auto hash (block_a->hash ()); - nano::unique_lock lock{ mutex }; - auto existing (blocks.find (hash)); + auto const hash = block_a->hash (); + std::shared_ptr election = nullptr; + { + nano::lock_guard guard{ mutex }; + auto existing = blocks.find (hash); + if (existing != blocks.end ()) + { + election = existing->second; + } + } + boost::optional status_type; - if (existing != blocks.end ()) + if (election) { - lock.unlock (); - nano::unique_lock election_lock{ existing->second->mutex }; - if (existing->second->status.winner && existing->second->status.winner->hash () == hash) + nano::unique_lock election_lock{ election->mutex }; + if (election->status.winner && election->status.winner->hash () == hash) { // Determine if the block was confirmed explicitly via election confirmation or implicitly via confirmation height - if (!existing->second->status_confirmed ()) + if (!election->status_confirmed ()) { - existing->second->confirm_once (election_lock, nano::election_status_type::active_confirmation_height); + election->confirm_once (election_lock, nano::election_status_type::active_confirmation_height); status_type = nano::election_status_type::active_confirmation_height; } else