Add started_elections topic to websockets (#3851)

This PR adds a new topic "started_elections" to websockets.

add observers.active_started for started elections

Update tests
This commit is contained in:
gr0vity-dev 2022-07-11 15:01:32 +02:00 committed by GitHub
commit 54e1c2ebbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 0 deletions

View file

@ -124,6 +124,54 @@ TEST (websocket, confirmation)
ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready);
}
// Tests getting notification of a started election
TEST (websocket, started_election)
{
nano::system system;
nano::node_config config (nano::get_available_port (), system.logging);
config.websocket_config.enabled = true;
config.websocket_config.port = nano::get_available_port ();
auto node1 = system.add_node (config);
std::atomic<bool> ack_ready{ false };
auto task = ([&ack_ready, config, &node1] () {
fake_websocket_client client (node1->websocket_server->listening_port ());
client.send_message (R"json({"action": "subscribe", "topic": "started_election", "ack": "true"})json");
client.await_ack ();
ack_ready = true;
EXPECT_EQ (1, node1->websocket_server->subscriber_count (nano::websocket::topic::started_election));
return client.get_response ();
});
auto future = std::async (std::launch::async, task);
ASSERT_TIMELY (5s, ack_ready);
// Create election, causing a websocket message to be emitted
nano::keypair key1;
nano::block_builder builder;
auto send1 = builder
.send ()
.previous (nano::dev::genesis->hash ())
.destination (key1.pub)
.balance (0)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*system.work.generate (nano::dev::genesis->hash ()))
.build_shared ();
nano::publish publish1{ nano::dev::network_params.network, send1 };
auto channel1 = node1->network.udp_channels.create (node1->network.endpoint ());
node1->network.inbound (publish1, channel1);
ASSERT_TIMELY (1s, node1->active.election (send1->qualified_root ()));
ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready);
auto response = future.get ();
ASSERT_TRUE (response);
boost::property_tree::ptree event;
std::stringstream stream;
stream << response.get ();
boost::property_tree::read_json (stream, event);
ASSERT_EQ (event.get<std::string> ("topic"), "started_election");
}
// Tests getting notification of an erased election
TEST (websocket, stopped_election)
{

View file

@ -847,6 +847,7 @@ nano::election_insertion_result nano::active_transactions::insert_impl (nano::un
auto const cache = find_inactive_votes_cache_impl (hash);
lock_a.unlock ();
result.election->insert_inactive_votes_cache (cache);
node.observers.active_started.notify (hash);
node.stats.inc (nano::stat::type::election, nano::stat::detail::election_start);
vacancy_update ();
}

View file

@ -282,6 +282,14 @@ nano::node::node (boost::asio::io_context & io_ctx_a, boost::filesystem::path co
}
});
observers.active_started.add ([this] (nano::block_hash const & hash_a) {
if (this->websocket_server->any_subscriber (nano::websocket::topic::started_election))
{
nano::websocket::message_builder builder;
this->websocket_server->broadcast (builder.started_election (hash_a));
}
});
observers.active_stopped.add ([this] (nano::block_hash const & hash_a) {
if (this->websocket_server->any_subscriber (nano::websocket::topic::stopped_election))
{

View file

@ -6,6 +6,7 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (na
composite->add_component (collect_container_info (node_observers.blocks, "blocks"));
composite->add_component (collect_container_info (node_observers.wallet, "wallet"));
composite->add_component (collect_container_info (node_observers.vote, "vote"));
composite->add_component (collect_container_info (node_observers.active_started, "active_started"));
composite->add_component (collect_container_info (node_observers.active_stopped, "active_stopped"));
composite->add_component (collect_container_info (node_observers.account_balance, "account_balance"));
composite->add_component (collect_container_info (node_observers.endpoint, "endpoint"));

View file

@ -15,6 +15,7 @@ public:
blocks_t blocks;
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;
nano::observer_set<nano::block_hash const &> active_stopped;
nano::observer_set<nano::account const &, bool> account_balance;
nano::observer_set<std::shared_ptr<nano::transport::channel>> endpoint;

View file

@ -375,6 +375,10 @@ nano::websocket::topic to_topic (std::string const & topic_a)
{
topic = nano::websocket::topic::confirmation;
}
else if (topic_a == "started_election")
{
topic = nano::websocket::topic::started_election;
}
else if (topic_a == "stopped_election")
{
topic = nano::websocket::topic::stopped_election;
@ -414,6 +418,10 @@ std::string from_topic (nano::websocket::topic topic_a)
{
topic = "confirmation";
}
else if (topic_a == nano::websocket::topic::started_election)
{
topic = "started_election";
}
else if (topic_a == nano::websocket::topic::stopped_election)
{
topic = "stopped_election";
@ -689,6 +697,18 @@ void nano::websocket::listener::decrease_subscriber_count (nano::websocket::topi
count -= 1;
}
nano::websocket::message nano::websocket::message_builder::started_election (nano::block_hash const & hash_a)
{
nano::websocket::message message_l (nano::websocket::topic::started_election);
set_common_fields (message_l);
boost::property_tree::ptree message_node_l;
message_node_l.add ("hash", hash_a.to_string ());
message_l.contents.add_child ("message", message_node_l);
return message_l;
}
nano::websocket::message nano::websocket::message_builder::stopped_election (nano::block_hash const & hash_a)
{
nano::websocket::message message_l (nano::websocket::topic::stopped_election);

View file

@ -41,6 +41,8 @@ namespace websocket
ack,
/** A confirmation message */
confirmation,
/** Started election message*/
started_election,
/** Stopped election message (dropped elections due to bounding or block lost the elections) */
stopped_election,
/** A vote message **/
@ -81,6 +83,7 @@ namespace websocket
{
public:
message block_confirmed (std::shared_ptr<nano::block> const & block_a, nano::account const & account_a, nano::amount const & amount_a, std::string subtype, bool include_block, nano::election_status const & election_status_a, std::vector<nano::vote_with_weight_info> const & election_votes_a, nano::websocket::confirmation_options const & options_a);
message started_election (nano::block_hash const & hash_a);
message stopped_election (nano::block_hash const & hash_a);
message vote_received (std::shared_ptr<nano::vote> const & vote_a, nano::vote_code code_a);
message work_generation (nano::work_version const version_a, nano::block_hash const & root_a, uint64_t const work_a, uint64_t const difficulty_a, uint64_t const publish_threshold_a, std::chrono::milliseconds const & duration_a, std::string const & peer_a, std::vector<std::string> const & bad_peers_a, bool const completed_a = true, bool const cancelled_a = false);