Election expose update action
This commit is contained in:
parent
c311aa67af
commit
238466cbfa
6 changed files with 61 additions and 25 deletions
|
|
@ -40,7 +40,7 @@ public:
|
|||
|
||||
std::shared_ptr<nano::election> random_election (nano::election_behavior behavior = nano::election_behavior::priority)
|
||||
{
|
||||
return std::make_shared<nano::election> (node, next_block (), nullptr, nullptr, behavior);
|
||||
return std::make_shared<nano::election> (node, next_block (), behavior);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ TEST (confirmation_solicitor, batches)
|
|||
nano::lock_guard<nano::mutex> guard (node2.active.mutex);
|
||||
for (size_t i (0); i < nano::network::confirm_req_hashes_max; ++i)
|
||||
{
|
||||
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::priority));
|
||||
auto election (std::make_shared<nano::election> (node2, send, nano::election_behavior::priority));
|
||||
ASSERT_FALSE (solicitor.add (*election));
|
||||
}
|
||||
// Reached the maximum amount of requests for the channel
|
||||
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::priority));
|
||||
auto election (std::make_shared<nano::election> (node2, send, nano::election_behavior::priority));
|
||||
// Broadcasting should be immediate
|
||||
ASSERT_EQ (0, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out));
|
||||
ASSERT_FALSE (solicitor.broadcast (*election));
|
||||
|
|
@ -92,7 +92,7 @@ TEST (confirmation_solicitor, different_hash)
|
|||
.work (*system.work.generate (nano::dev::genesis->hash ()))
|
||||
.build ();
|
||||
send->sideband_set ({});
|
||||
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::priority));
|
||||
auto election (std::make_shared<nano::election> (node2, send, nano::election_behavior::priority));
|
||||
// Add a vote for something else, not the winner
|
||||
election->last_votes[representative.account] = { std::chrono::steady_clock::now (), 1, 1 };
|
||||
// Ensure the request and broadcast goes through
|
||||
|
|
@ -136,7 +136,7 @@ TEST (confirmation_solicitor, bypass_max_requests_cap)
|
|||
.work (*system.work.generate (nano::dev::genesis->hash ()))
|
||||
.build ();
|
||||
send->sideband_set ({});
|
||||
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::priority));
|
||||
auto election (std::make_shared<nano::election> (node2, send, nano::election_behavior::priority));
|
||||
// Add a vote for something else, not the winner
|
||||
for (auto const & rep : representatives)
|
||||
{
|
||||
|
|
@ -149,7 +149,7 @@ TEST (confirmation_solicitor, bypass_max_requests_cap)
|
|||
ASSERT_TIMELY_EQ (6s, max_representatives + 1, node2.stats.count (nano::stat::type::message, nano::stat::detail::confirm_req, nano::stat::dir::out));
|
||||
|
||||
solicitor.prepare (representatives);
|
||||
auto election2 (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::priority));
|
||||
auto election2 (std::make_shared<nano::election> (node2, send, nano::election_behavior::priority));
|
||||
ASSERT_FALSE (solicitor.add (*election2));
|
||||
ASSERT_FALSE (solicitor.broadcast (*election2));
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ TEST (election, construction)
|
|||
nano::test::system system (1);
|
||||
auto & node = *system.nodes[0];
|
||||
auto election = std::make_shared<nano::election> (
|
||||
node, nano::dev::genesis, [] (auto const &) {}, [] (auto const &) {}, nano::election_behavior::priority);
|
||||
node, nano::dev::genesis, nano::election_behavior::priority, [] (auto const &) {}, [] (auto const &) {}, [] (auto const &) {});
|
||||
}
|
||||
|
||||
TEST (election, behavior)
|
||||
|
|
|
|||
|
|
@ -157,11 +157,16 @@ auto nano::active_elections::insert (std::shared_ptr<nano::block> const & block,
|
|||
|
||||
// Passing this callback into the election is important
|
||||
// We need to observe and update the online voting weight *before* election quorum is checked
|
||||
auto observe_rep_callback = [&node = node] (auto const & rep) {
|
||||
auto observe_rep_action = [&node = node] (auto const & rep) {
|
||||
node.online_reps.observe (rep);
|
||||
};
|
||||
|
||||
result.election = nano::make_shared<nano::election> (node, block, nullptr, observe_rep_callback, behavior);
|
||||
// On any election state update, schedule a call to tick it immediately
|
||||
auto update_action = [this] (auto const & root) {
|
||||
trigger (root);
|
||||
};
|
||||
|
||||
result.election = std::make_shared<nano::election> (node, block, behavior, nullptr, observe_rep_action, update_action);
|
||||
|
||||
// Store erased callback if provided
|
||||
if (erased_callback)
|
||||
|
|
@ -496,7 +501,8 @@ void nano::active_elections::tick_elections (nano::unique_lock<nano::mutex> & lo
|
|||
std::deque<std::shared_ptr<nano::election>> stale_elections;
|
||||
for (auto const & election : election_list)
|
||||
{
|
||||
if (election->transition_time (solicitor))
|
||||
bool tick_result = election->tick (solicitor);
|
||||
if (tick_result)
|
||||
{
|
||||
erase (election->qualified_root);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,10 @@ std::chrono::milliseconds nano::election::base_latency () const
|
|||
* election
|
||||
*/
|
||||
|
||||
nano::election::election (nano::node & node_a, std::shared_ptr<nano::block> const & block_a, std::function<void (std::shared_ptr<nano::block> const &)> const & confirmation_action_a, std::function<void (nano::account const &)> const & vote_action_a, nano::election_behavior election_behavior_a) :
|
||||
confirmation_action (confirmation_action_a),
|
||||
vote_action (vote_action_a),
|
||||
nano::election::election (nano::node & node_a, std::shared_ptr<nano::block> const & block_a, nano::election_behavior election_behavior_a, std::function<void (std::shared_ptr<nano::block> const &)> confirmation_action_a, std::function<void (nano::account const &)> vote_action_a, std::function<void (nano::qualified_root const &)> update_action_a) :
|
||||
confirmation_action (std::move (confirmation_action_a)),
|
||||
vote_action (std::move (vote_action_a)),
|
||||
update_action (std::move (update_action_a)),
|
||||
node (node_a),
|
||||
behavior_m (election_behavior_a),
|
||||
status (block_a),
|
||||
|
|
@ -78,14 +79,19 @@ void nano::election::confirm_once (nano::unique_lock<nano::mutex> & lock)
|
|||
|
||||
lock.unlock ();
|
||||
|
||||
node.active.trigger (qualified_root);
|
||||
if (update_action)
|
||||
{
|
||||
node.election_workers.post ([qualified_root_l = qualified_root, update_action_l = update_action] () {
|
||||
update_action_l (qualified_root_l);
|
||||
});
|
||||
}
|
||||
|
||||
node.election_workers.post ([status_l, confirmation_action_l = confirmation_action] () {
|
||||
if (confirmation_action_l)
|
||||
{
|
||||
if (confirmation_action)
|
||||
{
|
||||
node.election_workers.post ([status_l, confirmation_action_l = confirmation_action] () {
|
||||
confirmation_action_l (status_l.winner);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -149,6 +155,13 @@ bool nano::election::state_change (nano::election_state expected_a, nano::electi
|
|||
state_m = desired_a;
|
||||
state_start = std::chrono::steady_clock::now ().time_since_epoch ();
|
||||
result = false;
|
||||
|
||||
if (update_action)
|
||||
{
|
||||
node.election_workers.post ([qualified_root_l = qualified_root, update_action_l = update_action] () {
|
||||
update_action_l (qualified_root_l);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
@ -216,6 +229,13 @@ bool nano::election::transition_priority ()
|
|||
qualified_root,
|
||||
duration ().count ());
|
||||
|
||||
if (update_action)
|
||||
{
|
||||
node.election_workers.post ([qualified_root_l = qualified_root, update_action_l = update_action] () {
|
||||
update_action_l (qualified_root_l);
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +328,7 @@ nano::election_status nano::election::get_status () const
|
|||
return status;
|
||||
}
|
||||
|
||||
bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a)
|
||||
bool nano::election::tick (nano::confirmation_solicitor & solicitor)
|
||||
{
|
||||
nano::unique_lock<nano::mutex> lock{ mutex };
|
||||
bool result = false;
|
||||
|
|
@ -322,12 +342,12 @@ bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a
|
|||
break;
|
||||
case nano::election_state::active:
|
||||
broadcast_vote_locked (lock);
|
||||
broadcast_block (solicitor_a);
|
||||
send_confirm_req (solicitor_a);
|
||||
broadcast_block (solicitor);
|
||||
send_confirm_req (solicitor);
|
||||
break;
|
||||
case nano::election_state::confirmed:
|
||||
result = true; // Return true to indicate this election should be cleaned up
|
||||
broadcast_block (solicitor_a); // Ensure election winner is broadcasted
|
||||
broadcast_block (solicitor); // Ensure election winner is broadcasted
|
||||
state_change (nano::election_state::confirmed, nano::election_state::expired_confirmed);
|
||||
break;
|
||||
case nano::election_state::expired_unconfirmed:
|
||||
|
|
@ -353,6 +373,7 @@ bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a
|
|||
status.type = nano::election_status_type::stopped;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ private:
|
|||
// Callbacks
|
||||
std::function<void (std::shared_ptr<nano::block> const &)> confirmation_action;
|
||||
std::function<void (nano::account const &)> vote_action;
|
||||
std::function<void (nano::qualified_root const &)> update_action;
|
||||
|
||||
private: // State management
|
||||
static unsigned constexpr passive_duration_factor = 5;
|
||||
|
|
@ -89,7 +90,9 @@ private: // State management
|
|||
bool state_change (nano::election_state, nano::election_state);
|
||||
|
||||
public: // State transitions
|
||||
bool transition_time (nano::confirmation_solicitor &);
|
||||
// Returns true if the election should be cleaned up
|
||||
bool tick (nano::confirmation_solicitor &);
|
||||
|
||||
void transition_active ();
|
||||
bool transition_priority ();
|
||||
void cancel ();
|
||||
|
|
@ -110,7 +113,13 @@ public: // Status
|
|||
nano::election_status status;
|
||||
|
||||
public: // Interface
|
||||
election (nano::node &, std::shared_ptr<nano::block> const & block, std::function<void (std::shared_ptr<nano::block> const &)> const & confirmation_action, std::function<void (nano::account const &)> const & vote_action, nano::election_behavior behavior);
|
||||
election (
|
||||
nano::node &,
|
||||
std::shared_ptr<nano::block> const & block,
|
||||
nano::election_behavior behavior,
|
||||
std::function<void (std::shared_ptr<nano::block> const &)> confirmation_action = nullptr,
|
||||
std::function<void (nano::account const &)> vote_action = nullptr,
|
||||
std::function<void (nano::qualified_root const &)> update_action = nullptr);
|
||||
|
||||
std::shared_ptr<nano::block> find (nano::block_hash const &) const;
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue