Local block broadcaster (#4454)
* Add rolled back event * Local block broadcaster * Rate limit block broadcasting * Rename to `local_block_broadcaster` * Node initialization order * Fix tests * Bump local block queue size to 8k elements
This commit is contained in:
		
					parent
					
						
							
								65de6fe3e5
							
						
					
				
			
			
				commit
				
					
						5f28f1a8b8
					
				
			
		
					 13 changed files with 305 additions and 89 deletions
				
			
		| 
						 | 
				
			
			@ -49,6 +49,7 @@ enum class type : uint8_t
 | 
			
		|||
	election_scheduler,
 | 
			
		||||
	optimistic_scheduler,
 | 
			
		||||
	handshake,
 | 
			
		||||
	local_block_broadcaster,
 | 
			
		||||
 | 
			
		||||
	bootstrap_ascending,
 | 
			
		||||
	bootstrap_ascending_accounts,
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +103,7 @@ enum class detail : uint8_t
 | 
			
		|||
	old,
 | 
			
		||||
	gap_previous,
 | 
			
		||||
	gap_source,
 | 
			
		||||
	rollback,
 | 
			
		||||
	rollback_failed,
 | 
			
		||||
	progress,
 | 
			
		||||
	bad_signature,
 | 
			
		||||
| 
						 | 
				
			
			@ -328,6 +330,12 @@ enum class detail : uint8_t
 | 
			
		|||
	deprioritize,
 | 
			
		||||
	deprioritize_failed,
 | 
			
		||||
 | 
			
		||||
	// block broadcaster
 | 
			
		||||
	broadcast_normal,
 | 
			
		||||
	broadcast_aggressive,
 | 
			
		||||
	erase_old,
 | 
			
		||||
	erase_confirmed,
 | 
			
		||||
 | 
			
		||||
	_last // Must be the last enum
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,9 @@ std::string nano::thread_role::get_string (nano::thread_role::name role)
 | 
			
		|||
		case nano::thread_role::name::scheduler_priority:
 | 
			
		||||
			thread_role_name_string = "Sched Priority";
 | 
			
		||||
			break;
 | 
			
		||||
		case nano::thread_role::name::local_block_broadcasting:
 | 
			
		||||
			thread_role_name_string = "Local broadcast";
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			debug_assert (false && "nano::thread_role::get_string unhandled thread role");
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,7 @@ enum class name
 | 
			
		|||
	scheduler_manual,
 | 
			
		||||
	scheduler_optimistic,
 | 
			
		||||
	scheduler_priority,
 | 
			
		||||
	local_block_broadcasting,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,8 +20,6 @@ add_library(
 | 
			
		|||
  backlog_population.cpp
 | 
			
		||||
  bandwidth_limiter.hpp
 | 
			
		||||
  bandwidth_limiter.cpp
 | 
			
		||||
  block_broadcast.cpp
 | 
			
		||||
  block_broadcast.hpp
 | 
			
		||||
  blockprocessor.hpp
 | 
			
		||||
  blockprocessor.cpp
 | 
			
		||||
  bootstrap/block_deserializer.hpp
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +98,8 @@ add_library(
 | 
			
		|||
  ipc/ipc_server.cpp
 | 
			
		||||
  json_handler.hpp
 | 
			
		||||
  json_handler.cpp
 | 
			
		||||
  local_block_broadcaster.cpp
 | 
			
		||||
  local_block_broadcaster.hpp
 | 
			
		||||
  make_store.hpp
 | 
			
		||||
  make_store.cpp
 | 
			
		||||
  network.hpp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,51 +0,0 @@
 | 
			
		|||
#include <nano/node/block_broadcast.hpp>
 | 
			
		||||
#include <nano/node/blockprocessor.hpp>
 | 
			
		||||
#include <nano/node/network.hpp>
 | 
			
		||||
 | 
			
		||||
nano::block_broadcast::block_broadcast (nano::network & network, bool enabled) :
 | 
			
		||||
	network{ network },
 | 
			
		||||
	enabled{ enabled }
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nano::block_broadcast::connect (nano::block_processor & block_processor)
 | 
			
		||||
{
 | 
			
		||||
	if (!enabled)
 | 
			
		||||
	{
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	block_processor.block_processed.add ([this] (auto const & result, auto const & context) {
 | 
			
		||||
		switch (result)
 | 
			
		||||
		{
 | 
			
		||||
			case nano::block_status::progress:
 | 
			
		||||
				observe (context);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nano::block_broadcast::observe (nano::block_processor::context const & context)
 | 
			
		||||
{
 | 
			
		||||
	auto const & block = context.block;
 | 
			
		||||
	if (context.source == nano::block_source::local)
 | 
			
		||||
	{
 | 
			
		||||
		// Block created on this node
 | 
			
		||||
		// Perform more agressive initial flooding
 | 
			
		||||
		network.flood_block_initial (block);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (context.source != nano::block_source::bootstrap && context.source != nano::block_source::bootstrap_legacy)
 | 
			
		||||
		{
 | 
			
		||||
			// Block arrived from realtime traffic, do normal gossip.
 | 
			
		||||
			network.flood_block (block, nano::transport::buffer_drop_policy::limiter);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// Block arrived from bootstrap
 | 
			
		||||
			// Don't broadcast blocks we're bootstrapping
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,28 +0,0 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <nano/lib/blocks.hpp>
 | 
			
		||||
#include <nano/node/blockprocessor.hpp>
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <unordered_set>
 | 
			
		||||
 | 
			
		||||
namespace nano
 | 
			
		||||
{
 | 
			
		||||
class network;
 | 
			
		||||
 | 
			
		||||
// This class tracks blocks that originated from this node.
 | 
			
		||||
class block_broadcast
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	block_broadcast (nano::network & network, bool enabled = false);
 | 
			
		||||
	// Add batch_processed observer to block_processor if enabled
 | 
			
		||||
	void connect (nano::block_processor & block_processor);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	// Block_processor observer
 | 
			
		||||
	void observe (nano::block_processor::context const &);
 | 
			
		||||
 | 
			
		||||
	nano::network & network;
 | 
			
		||||
	bool enabled;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -152,11 +152,15 @@ void nano::block_processor::rollback_competitor (store::write_transaction const
 | 
			
		|||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			node.stats.inc (nano::stat::type::ledger, nano::stat::detail::rollback);
 | 
			
		||||
			node.logger.debug (nano::log::type::blockprocessor, "Blocks rolled back: {}", rollback_list.size ());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Deleting from votes cache, stop active transaction
 | 
			
		||||
		for (auto & i : rollback_list)
 | 
			
		||||
		{
 | 
			
		||||
			rolled_back.notify (i);
 | 
			
		||||
 | 
			
		||||
			node.history.erase (i->root ());
 | 
			
		||||
			// Stop all rolled back active transactions except initial
 | 
			
		||||
			if (i->hash () != successor->hash ())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,6 +86,7 @@ public: // Events
 | 
			
		|||
	// The batch observer feeds the processed observer
 | 
			
		||||
	nano::observer_set<nano::block_status const &, context const &> block_processed;
 | 
			
		||||
	nano::observer_set<processed_batch_t const &> batch_processed;
 | 
			
		||||
	nano::observer_set<std::shared_ptr<nano::block> const &> rolled_back;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	// Roll back block in the ledger that conflicts with 'block'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										170
									
								
								nano/node/local_block_broadcaster.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								nano/node/local_block_broadcaster.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,170 @@
 | 
			
		|||
#include <nano/lib/threading.hpp>
 | 
			
		||||
#include <nano/lib/utility.hpp>
 | 
			
		||||
#include <nano/node/blockprocessor.hpp>
 | 
			
		||||
#include <nano/node/local_block_broadcaster.hpp>
 | 
			
		||||
#include <nano/node/network.hpp>
 | 
			
		||||
#include <nano/node/node.hpp>
 | 
			
		||||
 | 
			
		||||
nano::local_block_broadcaster::local_block_broadcaster (nano::node & node_a, nano::block_processor & block_processor_a, nano::network & network_a, nano::stats & stats_a, bool enabled_a) :
 | 
			
		||||
	node{ node_a },
 | 
			
		||||
	block_processor{ block_processor_a },
 | 
			
		||||
	network{ network_a },
 | 
			
		||||
	stats{ stats_a },
 | 
			
		||||
	enabled{ enabled_a }
 | 
			
		||||
{
 | 
			
		||||
	if (!enabled)
 | 
			
		||||
	{
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	block_processor.batch_processed.add ([this] (auto const & batch) {
 | 
			
		||||
		bool should_notify = false;
 | 
			
		||||
		for (auto const & [result, context] : batch)
 | 
			
		||||
		{
 | 
			
		||||
			// Only rebroadcast local blocks that were successfully processed (no forks or gaps)
 | 
			
		||||
			if (result == nano::block_status::progress && context.source == nano::block_source::local)
 | 
			
		||||
			{
 | 
			
		||||
				nano::lock_guard<nano::mutex> guard{ mutex };
 | 
			
		||||
				local_blocks.emplace_back (local_entry{ context.block, std::chrono::steady_clock::now () });
 | 
			
		||||
				stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::insert);
 | 
			
		||||
				should_notify = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (should_notify)
 | 
			
		||||
		{
 | 
			
		||||
			condition.notify_all ();
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	block_processor.rolled_back.add ([this] (auto const & block) {
 | 
			
		||||
		nano::lock_guard<nano::mutex> guard{ mutex };
 | 
			
		||||
		auto erased = local_blocks.get<tag_hash> ().erase (block->hash ());
 | 
			
		||||
		stats.add (nano::stat::type::local_block_broadcaster, nano::stat::detail::rollback, nano::stat::dir::in, erased);
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nano::local_block_broadcaster::~local_block_broadcaster ()
 | 
			
		||||
{
 | 
			
		||||
	// Thread must be stopped before destruction
 | 
			
		||||
	debug_assert (!thread.joinable ());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nano::local_block_broadcaster::start ()
 | 
			
		||||
{
 | 
			
		||||
	if (!enabled)
 | 
			
		||||
	{
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	debug_assert (!thread.joinable ());
 | 
			
		||||
 | 
			
		||||
	thread = std::thread{ [this] () {
 | 
			
		||||
		nano::thread_role::set (nano::thread_role::name::local_block_broadcasting);
 | 
			
		||||
		run ();
 | 
			
		||||
	} };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nano::local_block_broadcaster::stop ()
 | 
			
		||||
{
 | 
			
		||||
	{
 | 
			
		||||
		nano::lock_guard<nano::mutex> lock{ mutex };
 | 
			
		||||
		stopped = true;
 | 
			
		||||
	}
 | 
			
		||||
	condition.notify_all ();
 | 
			
		||||
	nano::join_or_pass (thread);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nano::local_block_broadcaster::run ()
 | 
			
		||||
{
 | 
			
		||||
	nano::unique_lock<nano::mutex> lock{ mutex };
 | 
			
		||||
	while (!stopped)
 | 
			
		||||
	{
 | 
			
		||||
		stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::loop);
 | 
			
		||||
 | 
			
		||||
		condition.wait_for (lock, check_interval);
 | 
			
		||||
		debug_assert ((std::this_thread::yield (), true)); // Introduce some random delay in debug builds
 | 
			
		||||
 | 
			
		||||
		if (!stopped)
 | 
			
		||||
		{
 | 
			
		||||
			cleanup ();
 | 
			
		||||
			run_broadcasts (lock);
 | 
			
		||||
			debug_assert (lock.owns_lock ());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nano::local_block_broadcaster::run_broadcasts (nano::unique_lock<nano::mutex> & lock)
 | 
			
		||||
{
 | 
			
		||||
	debug_assert (lock.owns_lock ());
 | 
			
		||||
 | 
			
		||||
	std::vector<std::shared_ptr<nano::block>> to_broadcast;
 | 
			
		||||
 | 
			
		||||
	auto const now = std::chrono::steady_clock::now ();
 | 
			
		||||
	for (auto & entry : local_blocks)
 | 
			
		||||
	{
 | 
			
		||||
		if (elapsed (entry.last_broadcast, broadcast_interval, now))
 | 
			
		||||
		{
 | 
			
		||||
			entry.last_broadcast = now;
 | 
			
		||||
			to_broadcast.push_back (entry.block);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lock.unlock ();
 | 
			
		||||
 | 
			
		||||
	for (auto const & block : to_broadcast)
 | 
			
		||||
	{
 | 
			
		||||
		while (!limiter.should_pass (1))
 | 
			
		||||
		{
 | 
			
		||||
			std::this_thread::sleep_for (std::chrono::milliseconds{ 100 });
 | 
			
		||||
			if (stopped)
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::broadcast, nano::stat::dir::out);
 | 
			
		||||
 | 
			
		||||
		network.flood_block_initial (block);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lock.lock ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nano::local_block_broadcaster::cleanup ()
 | 
			
		||||
{
 | 
			
		||||
	debug_assert (!mutex.try_lock ());
 | 
			
		||||
 | 
			
		||||
	// Erase oldest blocks if the queue gets too big
 | 
			
		||||
	while (local_blocks.size () > max_size)
 | 
			
		||||
	{
 | 
			
		||||
		stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::erase_oldest);
 | 
			
		||||
		local_blocks.pop_front ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO: Mutex is held during IO, but it should be fine since it's not performance critical
 | 
			
		||||
	auto transaction = node.store.tx_begin_read ();
 | 
			
		||||
	erase_if (local_blocks, [this, &transaction] (auto const & entry) {
 | 
			
		||||
		transaction.refresh_if_needed ();
 | 
			
		||||
 | 
			
		||||
		if (entry.last_broadcast == std::chrono::steady_clock::time_point{})
 | 
			
		||||
		{
 | 
			
		||||
			// This block has never been broadcasted, keep it so it's broadcasted at least once
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		if (node.block_confirmed_or_being_confirmed (transaction, entry.block->hash ()))
 | 
			
		||||
		{
 | 
			
		||||
			stats.inc (nano::stat::type::local_block_broadcaster, nano::stat::detail::erase_confirmed);
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::unique_ptr<nano::container_info_component> nano::local_block_broadcaster::collect_container_info (const std::string & name) const
 | 
			
		||||
{
 | 
			
		||||
	nano::lock_guard<nano::mutex> guard{ mutex };
 | 
			
		||||
 | 
			
		||||
	auto composite = std::make_unique<container_info_composite> (name);
 | 
			
		||||
	composite->add_component (std::make_unique<container_info_leaf> (container_info{ "local", local_blocks.size (), sizeof (decltype (local_blocks)::value_type) }));
 | 
			
		||||
	return composite;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								nano/node/local_block_broadcaster.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								nano/node/local_block_broadcaster.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <nano/lib/blocks.hpp>
 | 
			
		||||
#include <nano/lib/locks.hpp>
 | 
			
		||||
#include <nano/lib/processing_queue.hpp>
 | 
			
		||||
#include <nano/node/bandwidth_limiter.hpp>
 | 
			
		||||
#include <nano/node/blockprocessor.hpp>
 | 
			
		||||
#include <nano/secure/common.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/multi_index/hashed_index.hpp>
 | 
			
		||||
#include <boost/multi_index/mem_fun.hpp>
 | 
			
		||||
#include <boost/multi_index/ordered_index.hpp>
 | 
			
		||||
#include <boost/multi_index/sequenced_index.hpp>
 | 
			
		||||
#include <boost/multi_index_container.hpp>
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <thread>
 | 
			
		||||
#include <unordered_set>
 | 
			
		||||
 | 
			
		||||
namespace mi = boost::multi_index;
 | 
			
		||||
 | 
			
		||||
namespace nano
 | 
			
		||||
{
 | 
			
		||||
class node;
 | 
			
		||||
class network;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace nano
 | 
			
		||||
{
 | 
			
		||||
/**
 | 
			
		||||
 * Broadcasts blocks to the network
 | 
			
		||||
 * Tracks local blocks for more aggressive propagation
 | 
			
		||||
 */
 | 
			
		||||
class local_block_broadcaster
 | 
			
		||||
{
 | 
			
		||||
	enum class broadcast_strategy
 | 
			
		||||
	{
 | 
			
		||||
		normal,
 | 
			
		||||
		aggressive,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	local_block_broadcaster (nano::node &, nano::block_processor &, nano::network &, nano::stats &, bool enabled = false);
 | 
			
		||||
	~local_block_broadcaster ();
 | 
			
		||||
 | 
			
		||||
	void start ();
 | 
			
		||||
	void stop ();
 | 
			
		||||
 | 
			
		||||
	std::unique_ptr<container_info_component> collect_container_info (std::string const & name) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void run ();
 | 
			
		||||
	void run_broadcasts (nano::unique_lock<nano::mutex> &);
 | 
			
		||||
	void cleanup ();
 | 
			
		||||
 | 
			
		||||
private: // Dependencies
 | 
			
		||||
	nano::node & node;
 | 
			
		||||
	nano::block_processor & block_processor;
 | 
			
		||||
	nano::network & network;
 | 
			
		||||
	nano::stats & stats;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	struct local_entry
 | 
			
		||||
	{
 | 
			
		||||
		std::shared_ptr<nano::block> const block;
 | 
			
		||||
		std::chrono::steady_clock::time_point const arrival;
 | 
			
		||||
		mutable std::chrono::steady_clock::time_point last_broadcast{}; // Not part of any index
 | 
			
		||||
 | 
			
		||||
		nano::block_hash hash () const
 | 
			
		||||
		{
 | 
			
		||||
			return block->hash ();
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// clang-format off
 | 
			
		||||
	class tag_sequenced	{};
 | 
			
		||||
	class tag_hash {};
 | 
			
		||||
 | 
			
		||||
	using ordered_locals = boost::multi_index_container<local_entry,
 | 
			
		||||
	mi::indexed_by<
 | 
			
		||||
		mi::sequenced<mi::tag<tag_sequenced>>,
 | 
			
		||||
		mi::hashed_unique<mi::tag<tag_hash>,
 | 
			
		||||
			mi::const_mem_fun<local_entry, nano::block_hash, &local_entry::hash>>
 | 
			
		||||
	>>;
 | 
			
		||||
	// clang-format on
 | 
			
		||||
 | 
			
		||||
	ordered_locals local_blocks;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	bool enabled{ false };
 | 
			
		||||
 | 
			
		||||
	nano::bandwidth_limiter limiter{ broadcast_rate_limit, broadcast_rate_burst_ratio };
 | 
			
		||||
 | 
			
		||||
	std::atomic<bool> stopped{ false };
 | 
			
		||||
	nano::condition_variable condition;
 | 
			
		||||
	mutable nano::mutex mutex;
 | 
			
		||||
	std::thread thread;
 | 
			
		||||
 | 
			
		||||
	// TODO: Make these configurable
 | 
			
		||||
	static std::size_t constexpr max_size{ 1024 * 8 };
 | 
			
		||||
	static std::chrono::seconds constexpr check_interval{ 30 };
 | 
			
		||||
	static std::chrono::seconds constexpr broadcast_interval{ 60 };
 | 
			
		||||
	static std::size_t constexpr broadcast_rate_limit{ 32 };
 | 
			
		||||
	static double constexpr broadcast_rate_burst_ratio{ 3 };
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -195,14 +195,13 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons
 | 
			
		|||
	ascendboot{ config, block_processor, ledger, network, stats },
 | 
			
		||||
	websocket{ config.websocket_config, observers, wallets, ledger, io_ctx, logger },
 | 
			
		||||
	epoch_upgrader{ *this, ledger, store, network_params, logger },
 | 
			
		||||
	local_block_broadcaster{ *this, block_processor, network, stats, !flags.disable_block_processor_republishing },
 | 
			
		||||
	process_live_dispatcher{ ledger, scheduler.priority, vote_cache, websocket },
 | 
			
		||||
	startup_time (std::chrono::steady_clock::now ()),
 | 
			
		||||
	node_seq (seq),
 | 
			
		||||
	block_broadcast{ network, !flags.disable_block_processor_republishing },
 | 
			
		||||
	process_live_dispatcher{ ledger, scheduler.priority, vote_cache, websocket }
 | 
			
		||||
	node_seq (seq)
 | 
			
		||||
{
 | 
			
		||||
	logger.debug (nano::log::type::node, "Constructing node...");
 | 
			
		||||
 | 
			
		||||
	block_broadcast.connect (block_processor);
 | 
			
		||||
	process_live_dispatcher.connect (block_processor);
 | 
			
		||||
 | 
			
		||||
	unchecked.satisfied.add ([this] (nano::unchecked_info const & info) {
 | 
			
		||||
| 
						 | 
				
			
			@ -551,6 +550,7 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (no
 | 
			
		|||
	composite->add_component (collect_container_info (node.final_generator, "vote_generator_final"));
 | 
			
		||||
	composite->add_component (node.ascendboot.collect_container_info ("bootstrap_ascending"));
 | 
			
		||||
	composite->add_component (node.unchecked.collect_container_info ("unchecked"));
 | 
			
		||||
	composite->add_component (node.local_block_broadcaster.collect_container_info ("local_block_broadcaster"));
 | 
			
		||||
	return composite;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -659,6 +659,7 @@ void nano::node::start ()
 | 
			
		|||
	}
 | 
			
		||||
	websocket.start ();
 | 
			
		||||
	telemetry.start ();
 | 
			
		||||
	local_block_broadcaster.start ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void nano::node::stop ()
 | 
			
		||||
| 
						 | 
				
			
			@ -699,6 +700,7 @@ void nano::node::stop ()
 | 
			
		|||
	stats.stop ();
 | 
			
		||||
	epoch_upgrader.stop ();
 | 
			
		||||
	workers.stop ();
 | 
			
		||||
	local_block_broadcaster.stop ();
 | 
			
		||||
	// work pool is not stopped on purpose due to testing setup
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@
 | 
			
		|||
#include <nano/node/active_transactions.hpp>
 | 
			
		||||
#include <nano/node/backlog_population.hpp>
 | 
			
		||||
#include <nano/node/bandwidth_limiter.hpp>
 | 
			
		||||
#include <nano/node/block_broadcast.hpp>
 | 
			
		||||
#include <nano/node/blockprocessor.hpp>
 | 
			
		||||
#include <nano/node/bootstrap/bootstrap.hpp>
 | 
			
		||||
#include <nano/node/bootstrap/bootstrap_attempt.hpp>
 | 
			
		||||
| 
						 | 
				
			
			@ -18,6 +17,7 @@
 | 
			
		|||
#include <nano/node/distributed_work_factory.hpp>
 | 
			
		||||
#include <nano/node/election.hpp>
 | 
			
		||||
#include <nano/node/epoch_upgrader.hpp>
 | 
			
		||||
#include <nano/node/local_block_broadcaster.hpp>
 | 
			
		||||
#include <nano/node/network.hpp>
 | 
			
		||||
#include <nano/node/node_observers.hpp>
 | 
			
		||||
#include <nano/node/nodeconfig.hpp>
 | 
			
		||||
| 
						 | 
				
			
			@ -186,7 +186,7 @@ public:
 | 
			
		|||
	nano::bootstrap_ascending::service ascendboot;
 | 
			
		||||
	nano::websocket_server websocket;
 | 
			
		||||
	nano::epoch_upgrader epoch_upgrader;
 | 
			
		||||
	nano::block_broadcast block_broadcast;
 | 
			
		||||
	nano::local_block_broadcaster local_block_broadcaster;
 | 
			
		||||
	nano::process_live_dispatcher process_live_dispatcher;
 | 
			
		||||
 | 
			
		||||
	std::chrono::steady_clock::time_point const startup_time;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2228,7 +2228,7 @@ TEST (rpc, block_count_pruning)
 | 
			
		|||
				 .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
 | 
			
		||||
				 .work (*node1->work_generate_blocking (latest))
 | 
			
		||||
				 .build ();
 | 
			
		||||
	node1->process_active (send1);
 | 
			
		||||
	node1->process_local (send1);
 | 
			
		||||
	auto receive1 = builder
 | 
			
		||||
					.receive ()
 | 
			
		||||
					.previous (send1->hash ())
 | 
			
		||||
| 
						 | 
				
			
			@ -2236,7 +2236,7 @@ TEST (rpc, block_count_pruning)
 | 
			
		|||
					.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
 | 
			
		||||
					.work (*node1->work_generate_blocking (send1->hash ()))
 | 
			
		||||
					.build ();
 | 
			
		||||
	node1->process_active (receive1);
 | 
			
		||||
	node1->process_local (receive1);
 | 
			
		||||
	system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
 | 
			
		||||
	ASSERT_TIMELY (5s, node1->block_confirmed (receive1->hash ()));
 | 
			
		||||
	// Pruning action
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue