Merge pull request #4505 from clemahieu/active_confirmed_simplify
Fix active_transactions missed notifications
This commit is contained in:
commit
a709bf19fb
7 changed files with 45 additions and 85 deletions
|
@ -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 ())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ());
|
||||
|
|
|
@ -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 &);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue