Merge pull request #4505 from clemahieu/active_confirmed_simplify

Fix active_transactions missed notifications
This commit is contained in:
clemahieu 2024-03-20 08:01:33 +00:00 committed by GitHub
commit a709bf19fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 45 additions and 85 deletions

View file

@ -162,6 +162,18 @@ bool nano::block::is_change () const noexcept
}
}
bool nano::block::is_epoch () const noexcept
{
release_assert (has_sideband ());
switch (type ())
{
case nano::block_type::state:
return sideband ().details.is_epoch;
default:
return false;
}
}
nano::block_hash const & nano::block::hash () const
{
if (!cached_hash.is_zero ())

View file

@ -55,6 +55,7 @@ public:
bool is_send () const noexcept;
bool is_receive () const noexcept;
bool is_change () const noexcept;
bool is_epoch () const noexcept;
public: // Direct access to the block fields or nullopt if the block type does not have the specified field
// Returns account field or account from sideband

View file

@ -82,12 +82,12 @@ void nano::active_transactions::stop ()
void nano::active_transactions::block_cemented_callback (std::shared_ptr<nano::block> const & block_a)
{
auto transaction = node.store.tx_begin_read ();
auto status_type = election_status (transaction, block_a);
auto status_type = election_status (block_a);
if (!status_type)
return;
auto transaction = node.store.tx_begin_read ();
switch (*status_type)
{
case nano::election_status_type::inactive_confirmation_height:
@ -102,13 +102,13 @@ void nano::active_transactions::block_cemented_callback (std::shared_ptr<nano::b
handle_final_votes_confirmation (block_a, transaction, *status_type);
}
boost::optional<nano::election_status_type> nano::active_transactions::election_status (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block)
boost::optional<nano::election_status_type> nano::active_transactions::election_status (std::shared_ptr<nano::block> const & block)
{
boost::optional<nano::election_status_type> status_type;
if (!confirmation_height_processor.is_processing_added_block (block->hash ()))
{
status_type = confirm_block (transaction, block);
status_type = confirm_block (block);
}
else
{
@ -120,13 +120,8 @@ boost::optional<nano::election_status_type> nano::active_transactions::election_
void nano::active_transactions::process_inactive_confirmation (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block)
{
nano::account account;
nano::uint128_t amount{ 0 };
bool is_state_send = false;
bool is_state_epoch = false;
nano::account pending_account{};
node.process_confirmed_data (transaction, block, block->hash (), account, amount, is_state_send, is_state_epoch, pending_account);
node.observers.blocks.notify (nano::election_status{ block, 0, 0, std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ()), std::chrono::duration_values<std::chrono::milliseconds>::zero (), 0, 1, 0, nano::election_status_type::inactive_confirmation_height }, {}, account, amount, is_state_send, is_state_epoch);
nano::election_status status{ block, 0, 0, std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now ().time_since_epoch ()), std::chrono::duration_values<std::chrono::milliseconds>::zero (), 0, 1, 0, nano::election_status_type::inactive_confirmation_height };
notify_observers (transaction, status, {});
}
void nano::active_transactions::process_active_confirmation (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block, nano::election_status_type status_type)
@ -151,38 +146,26 @@ void nano::active_transactions::handle_confirmation (nano::store::read_transacti
nano::block_hash hash = block->hash ();
recently_cemented.put (election->get_status ());
nano::account account;
nano::uint128_t amount (0);
bool is_state_send = false;
bool is_state_epoch = false;
nano::account pending_account;
handle_block_confirmation (transaction, block, hash, account, amount, is_state_send, is_state_epoch, pending_account);
auto status = election->set_status_type (status_type);
auto votes = election->votes_with_weight ();
notify_observers (status, votes, account, amount, is_state_send, is_state_epoch, pending_account);
notify_observers (transaction, status, votes);
}
void nano::active_transactions::handle_block_confirmation (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block, nano::block_hash const & hash, nano::account & account, nano::uint128_t & amount, bool & is_state_send, bool & is_state_epoch, nano::account & pending_account)
{
if (block->is_send ())
{
node.receive_confirmed (transaction, hash, block->destination ());
}
node.process_confirmed_data (transaction, block, hash, account, amount, is_state_send, is_state_epoch, pending_account);
}
void nano::active_transactions::notify_observers (nano::election_status const & status, std::vector<nano::vote_with_weight_info> const & votes, nano::account const & account, nano::uint128_t amount, bool is_state_send, bool is_state_epoch, nano::account const & pending_account)
void nano::active_transactions::notify_observers (nano::store::read_transaction const & transaction, nano::election_status const & status, std::vector<nano::vote_with_weight_info> const & votes)
{
auto block = status.winner;
auto account = block->account ();
auto amount = node.ledger.amount (transaction, block->hash ()).value_or (0);
auto is_state_send = block->type () == block_type::state && block->is_send ();
auto is_state_epoch = block->type () == block_type::state && block->is_epoch ();
node.observers.blocks.notify (status, votes, account, amount, is_state_send, is_state_epoch);
if (amount > 0)
{
node.observers.account_balance.notify (account, false);
if (!pending_account.is_zero ())
if (block->is_send ())
{
node.observers.account_balance.notify (pending_account, true);
node.observers.account_balance.notify (block->destination (), true);
}
}
}
@ -196,16 +179,16 @@ void nano::active_transactions::handle_final_votes_confirmation (std::shared_ptr
// Next-block activations are only done for blocks with previously active elections
if (cemented_bootstrap_count_reached && was_active)
{
activate_successors (account, block, transaction);
activate_successors (transaction, block);
}
}
void nano::active_transactions::activate_successors (const nano::account & account, std::shared_ptr<nano::block> const & block, nano::store::read_transaction const & transaction)
void nano::active_transactions::activate_successors (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block)
{
node.scheduler.priority.activate (account, transaction);
node.scheduler.priority.activate (block->account (), transaction);
// Start or vote for the next unconfirmed block in the destination account
if (block->is_send () && !block->destination ().is_zero () && block->destination () != account)
if (block->is_send () && !block->destination ().is_zero () && block->destination () != block->account ())
{
node.scheduler.priority.activate (block->destination (), transaction);
}
@ -671,7 +654,7 @@ bool nano::active_transactions::publish (std::shared_ptr<nano::block> const & bl
}
// Returns the type of election status requiring callbacks calling later
boost::optional<nano::election_status_type> nano::active_transactions::confirm_block (store::transaction const & transaction_a, std::shared_ptr<nano::block> const & block_a)
boost::optional<nano::election_status_type> nano::active_transactions::confirm_block (std::shared_ptr<nano::block> const & block_a)
{
auto const hash = block_a->hash ();
std::shared_ptr<nano::election> election = nullptr;

View file

@ -160,7 +160,7 @@ public:
bool empty () const;
std::size_t size () const;
bool publish (std::shared_ptr<nano::block> const &);
boost::optional<nano::election_status_type> confirm_block (store::transaction const &, std::shared_ptr<nano::block> const &);
boost::optional<nano::election_status_type> confirm_block (std::shared_ptr<nano::block> const &);
void block_cemented_callback (std::shared_ptr<nano::block> const &);
void block_already_cemented_callback (nano::block_hash const &);
@ -195,14 +195,13 @@ private:
* TODO: Should be moved to `vote_cache` class
*/
void add_vote_cache (nano::block_hash const & hash, std::shared_ptr<nano::vote> vote);
boost::optional<nano::election_status_type> election_status (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block);
boost::optional<nano::election_status_type> election_status (std::shared_ptr<nano::block> const & block);
void process_inactive_confirmation (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block);
void process_active_confirmation (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block, nano::election_status_type status);
void handle_final_votes_confirmation (std::shared_ptr<nano::block> const & block, nano::store::read_transaction const & transaction, nano::election_status_type status);
void handle_confirmation (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block, std::shared_ptr<nano::election> election, nano::election_status_type status);
void activate_successors (const nano::account & account, std::shared_ptr<nano::block> const & block, nano::store::read_transaction const & transaction);
void handle_block_confirmation (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block, nano::block_hash const & hash, nano::account & account, nano::uint128_t & amount, bool & is_state_send, bool & is_state_epoch, nano::account & pending_account);
void notify_observers (nano::election_status const & status, std::vector<nano::vote_with_weight_info> const & votes, nano::account const & account, nano::uint128_t amount, bool is_state_send, bool is_state_epoch, nano::account const & pending_account);
void activate_successors (nano::store::read_transaction const & transaction, std::shared_ptr<nano::block> const & block);
void notify_observers (nano::store::read_transaction const & transaction, nano::election_status const & status, std::vector<nano::vote_with_weight_info> const & votes);
private: // Dependencies
nano::node & node;

View file

@ -435,6 +435,13 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
std::exit (1);
}
}
confirmation_height_processor.add_cemented_observer ([this] (auto const & block) {
if (block->is_send ())
{
auto transaction = store.tx_begin_read ();
receive_confirmed (transaction, block->hash (), block->destination ());
}
});
}
node_initialized_latch.count_down ();
}
@ -1212,47 +1219,6 @@ void nano::node::receive_confirmed (store::transaction const & block_transaction
}
}
void nano::node::process_confirmed_data (store::transaction const & transaction_a, std::shared_ptr<nano::block> const & block_a, nano::block_hash const & hash_a, nano::account & account_a, nano::uint128_t & amount_a, bool & is_state_send_a, bool & is_state_epoch_a, nano::account & pending_account_a)
{
// Faster account calculation
account_a = block_a->account ();
// Faster amount calculation
auto previous (block_a->previous ());
auto previous_balance = ledger.balance (transaction_a, previous);
auto block_balance = block_a->balance ();
if (hash_a != ledger.constants.genesis->account ())
{
if (previous_balance)
{
amount_a = block_balance > previous_balance.value () ? block_balance.number () - previous_balance.value () : previous_balance.value () - block_balance.number ();
}
else
{
amount_a = 0;
}
}
else
{
amount_a = nano::dev::constants.genesis_amount;
}
if (auto state = dynamic_cast<nano::state_block *> (block_a.get ()))
{
if (state->hashables.balance < previous_balance)
{
is_state_send_a = true;
}
if (amount_a == 0 && network_params.ledger.epochs.is_epoch_link (state->link_field ().value ()))
{
is_state_epoch_a = true;
}
pending_account_a = state->hashables.link.as_account ();
}
if (auto send = dynamic_cast<nano::send_block *> (block_a.get ()))
{
pending_account_a = send->hashables.destination;
}
}
void nano::node::process_confirmed (nano::election_status const & status_a, uint64_t iteration_a)
{
auto hash (status_a.winner->hash ());

View file

@ -83,7 +83,6 @@ public:
std::shared_ptr<nano::node> shared ();
int store_version ();
void receive_confirmed (store::transaction const & block_transaction_a, nano::block_hash const & hash_a, nano::account const & destination_a);
void process_confirmed_data (store::transaction const &, std::shared_ptr<nano::block> const &, nano::block_hash const &, nano::account &, nano::uint128_t &, bool &, bool &, nano::account &);
void process_confirmed (nano::election_status const &, uint64_t = 0);
void process_active (std::shared_ptr<nano::block> const &);
std::optional<nano::block_status> process_local (std::shared_ptr<nano::block> const &);

View file

@ -12,7 +12,7 @@ class node_observers final
{
public:
using blocks_t = nano::observer_set<nano::election_status const &, std::vector<nano::vote_with_weight_info> const &, nano::account const &, nano::uint128_t const &, bool, bool>;
blocks_t blocks;
blocks_t blocks; // Notification upon election completion or cancellation
nano::observer_set<bool> wallet;
nano::observer_set<std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>, nano::vote_code> vote;
nano::observer_set<nano::block_hash const &> active_started;