Skip to content

Commit

Permalink
adjust testcase. Make vote_rebroadcaster interval configurable for te…
Browse files Browse the repository at this point in the history
…stcase
  • Loading branch information
gr0vity committed Feb 6, 2025
1 parent d2811db commit 01324d1
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 10 deletions.
12 changes: 9 additions & 3 deletions nano/core_test/vote_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ TEST (vote_processor, no_broadcast_local_with_a_principal_representative)
flags.disable_request_loop = true;
nano::node_config config1, config2;
config1.backlog_scan.enable = false;
config1.vote_rebroadcaster.interval = 10ms;
auto & node (*system.add_node (config1, flags));
config2.backlog_scan.enable = false;
config2.peering_port = system.get_available_port ();
Expand Down Expand Up @@ -291,7 +292,7 @@ TEST (vote_processor, no_broadcast_local_with_a_principal_representative)
ASSERT_TRUE (node.wallets.reps ().exists (nano::dev::genesis_key.pub));
ASSERT_TRUE (node.wallets.reps ().have_half_rep ()); // Genesis balance after `send' is over both half_rep and PR threshold.
// Process a vote with a key that is in the local wallet.
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch (), nano::vote::duration_max, std::vector<nano::block_hash>{ send->hash () });
auto vote = nano::test::make_final_vote (nano::dev::genesis_key, std::vector<std::shared_ptr<nano::block>>{ send });
ASSERT_EQ (nano::vote_code::vote, node.vote_router.vote (vote).at (send->hash ()));
// Make sure the vote was processed.
auto election (node.active.election (send->qualified_root ()));
Expand All @@ -300,8 +301,13 @@ TEST (vote_processor, no_broadcast_local_with_a_principal_representative)
auto existing (votes.find (nano::dev::genesis_key.pub));
ASSERT_NE (votes.end (), existing);
ASSERT_EQ (vote->timestamp (), existing->second.timestamp);
// Ensure the vote was not broadcast.
ASSERT_EQ (0, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out));

// The vote will be broadcast by the original node
ASSERT_TIMELY_EQ (5s, 1, node.stats.count (nano::stat::type::vote_generator, nano::stat::detail::generator_broadcasts));
std::this_thread::sleep_for (200ms);
// The vote will be broadcast by the original node once but should not be republished
// It's in candidate set and broadcast during the run() loop
ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out));
ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out));
}

Expand Down
2 changes: 1 addition & 1 deletion nano/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ nano::node::node (std::shared_ptr<boost::asio::io_context> io_ctx_a, std::filesy
http_callbacks{ *http_callbacks_impl },
pruning_impl{ std::make_unique<nano::pruning> (config, flags, ledger, stats, logger) },
pruning{ *pruning_impl },
vote_rebroadcaster_impl{ std::make_unique<nano::vote_rebroadcaster> (vote_router, network, wallets, stats, logger) },
vote_rebroadcaster_impl{ std::make_unique<nano::vote_rebroadcaster> (config.vote_rebroadcaster, vote_router, network, wallets, stats, logger) },
vote_rebroadcaster{ *vote_rebroadcaster_impl },
startup_time{ std::chrono::steady_clock::now () },
node_seq{ seq }
Expand Down
10 changes: 10 additions & 0 deletions nano/node/nodeconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const
bounded_backlog.serialize (bounded_backlog_l);
toml.put_child ("bounded_backlog", bounded_backlog_l);

nano::tomlconfig vote_rebroadcaster_l;
vote_rebroadcaster.serialize (vote_rebroadcaster_l);
toml.put_child ("vote_rebroadcaster", vote_rebroadcaster_l);

return toml.get_error ();
}

Expand Down Expand Up @@ -431,6 +435,12 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml)
bounded_backlog.deserialize (config_l);
}

if (toml.has_key ("vote_rebroadcaster"))
{
auto config_l = toml.get_required_child ("vote_rebroadcaster");
vote_rebroadcaster.deserialize (config_l);
}

/*
* Values
*/
Expand Down
2 changes: 2 additions & 0 deletions nano/node/nodeconfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <nano/node/transport/tcp_listener.hpp>
#include <nano/node/vote_cache.hpp>
#include <nano/node/vote_processor.hpp>
#include <nano/node/vote_rebroadcaster.hpp>
#include <nano/node/websocketconfig.hpp>
#include <nano/secure/common.hpp>
#include <nano/secure/generate_cache_flags.hpp>
Expand Down Expand Up @@ -152,6 +153,7 @@ class node_config
nano::monitor_config monitor;
nano::backlog_scan_config backlog_scan;
nano::bounded_backlog_config bounded_backlog;
nano::vote_rebroadcaster_config vote_rebroadcaster;

public:
/** Entry is ignored if it cannot be parsed as a valid address:port */
Expand Down
25 changes: 23 additions & 2 deletions nano/node/vote_rebroadcaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
#include <nano/node/wallet.hpp>
#include <nano/secure/vote.hpp>

nano::vote_rebroadcaster::vote_rebroadcaster (nano::vote_router & vote_router_a, nano::network & network_a, nano::wallets & wallets_a, nano::stats & stats_a, nano::logger & logger_a) :
nano::vote_rebroadcaster::vote_rebroadcaster (vote_rebroadcaster_config const & config_a, nano::vote_router & vote_router_a, nano::network & network_a, nano::wallets & wallets_a, nano::stats & stats_a, nano::logger & logger_a) :
config{ config_a },
vote_router{ vote_router_a },
network{ network_a },
wallets{ wallets_a },
Expand Down Expand Up @@ -96,7 +97,7 @@ void nano::vote_rebroadcaster::run ()

stats.inc (nano::stat::type::vote_rebroadcaster, nano::stat::detail::loop);

if (refresh_interval.elapse (15s))
if (refresh_interval.elapse (config.interval))
{
stats.inc (nano::stat::type::vote_rebroadcaster, nano::stat::detail::refresh);

Expand All @@ -109,13 +110,19 @@ void nano::vote_rebroadcaster::run ()
auto vote = queue.front ();
queue.pop_front ();

if (!enable)
{
continue; // Discard votes added while the node was not a representative
}

lock.unlock ();

stats.inc (nano::stat::type::vote_rebroadcaster, nano::stat::detail::rebroadcast);
stats.add (nano::stat::type::vote_rebroadcaster, nano::stat::detail::rebroadcast_hashes, vote->hashes.size ());
network.flood_vote (vote, 0.5f, /* rebroadcasted */ true); // TODO: Track number of peers that we sent the vote to

lock.lock ();

}
}
}
Expand All @@ -127,4 +134,18 @@ nano::container_info nano::vote_rebroadcaster::container_info () const
nano::container_info info;
info.put ("queue", queue.size ());
return info;
}

nano::error nano::vote_rebroadcaster_config::serialize (nano::tomlconfig & toml) const
{
toml.put ("interval", interval.count (), "Time between rebroadcast operations in milliseconds\ntype:uint64");
return toml.get_error ();
}

nano::error nano::vote_rebroadcaster_config::deserialize (nano::tomlconfig & toml)
{
auto interval_l = interval.count ();
toml.get ("interval", interval_l);
interval = std::chrono::milliseconds (interval_l);
return toml.get_error ();
}
17 changes: 13 additions & 4 deletions nano/node/vote_rebroadcaster.hpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
#pragma once

#include <nano/lib/interval.hpp>
#include <nano/node/fwd.hpp>
#include <nano/node/wallet.hpp>

#include <atomic>
#include <condition_variable>
#include <deque>
#include <thread>
#include <chrono>

namespace nano
{
class vote_rebroadcaster_config final
{
public:
std::chrono::milliseconds interval{ std::chrono::milliseconds{ 15'000 } }; // 15 seconds default

nano::error serialize (nano::tomlconfig & toml) const;
nano::error deserialize (nano::tomlconfig & toml);
};

class vote_rebroadcaster final
{
public:
static size_t constexpr max_queue = 1024 * 16;

public:
vote_rebroadcaster (nano::vote_router &, nano::network &, nano::wallets &, nano::stats &, nano::logger &);
vote_rebroadcaster (vote_rebroadcaster_config const &, nano::vote_router &, nano::network &, nano::wallets &, nano::stats &, nano::logger &);
~vote_rebroadcaster ();

void start ();
Expand All @@ -37,6 +45,7 @@ class vote_rebroadcaster final
void run ();

std::atomic<bool> enable{ true }; // Enable vote rebroadcasting only if the node does not host a representative
vote_rebroadcaster_config const & config;
std::deque<std::shared_ptr<nano::vote>> queue;
nano::wallet_representatives reps;
nano::interval refresh_interval;
Expand Down

0 comments on commit 01324d1

Please sign in to comment.