Websocket: Add linked_account to block content of confirmation topic
		
	- Add proper `linked_account` to the block content for send, receive, and open blocks when the `include_linked_account` option is enabled. - For change and epoch blocks, `linked_account` is set to "0", maintaining consistency with the `source` field in the blocks_info RPC response. Co-authored-by: clemahieu <clemahieu@gmail.com> Co-authored-by: gr0vity <gr0vity.dev@gmail.com>
This commit is contained in:
		
					parent
					
						
							
								99f95a11b5
							
						
					
				
			
			
				commit
				
					
						53fa92954e
					
				
			
		
					 7 changed files with 243 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -463,6 +463,177 @@ TEST (websocket, confirmation_options_votes)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST (websocket, confirmation_options_linked_account)
 | 
			
		||||
{
 | 
			
		||||
	nano::test::system system;
 | 
			
		||||
	nano::node_config config = system.default_config ();
 | 
			
		||||
	config.websocket_config.enabled = true;
 | 
			
		||||
	config.websocket_config.port = system.get_available_port ();
 | 
			
		||||
	auto node1 (system.add_node (config));
 | 
			
		||||
 | 
			
		||||
	std::atomic<bool> ack_ready{ false };
 | 
			
		||||
	auto task1 = ([&ack_ready, config, &node1] () {
 | 
			
		||||
		fake_websocket_client client (node1->websocket.server->listening_port ());
 | 
			
		||||
		client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {"confirmation_type": "active_quorum", "include_block": "true", "include_linked_account": "true"}})json");
 | 
			
		||||
		client.await_ack ();
 | 
			
		||||
		ack_ready = true;
 | 
			
		||||
		EXPECT_EQ (1, node1->websocket.server->subscriber_count (nano::websocket::topic::confirmation));
 | 
			
		||||
		return client.get_response ();
 | 
			
		||||
	});
 | 
			
		||||
	auto future1 = std::async (std::launch::async, task1);
 | 
			
		||||
 | 
			
		||||
	ASSERT_TIMELY (10s, ack_ready);
 | 
			
		||||
 | 
			
		||||
	// Confirm a state block for an in-wallet account
 | 
			
		||||
	system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
 | 
			
		||||
	nano::keypair key;
 | 
			
		||||
	auto balance = nano::dev::constants.genesis_amount;
 | 
			
		||||
	auto send_amount = node1->config.online_weight_minimum.number () + 1;
 | 
			
		||||
	nano::block_hash previous (node1->latest (nano::dev::genesis_key.pub));
 | 
			
		||||
	{
 | 
			
		||||
		nano::state_block_builder builder;
 | 
			
		||||
		balance -= send_amount;
 | 
			
		||||
		auto send = builder
 | 
			
		||||
					.account (nano::dev::genesis_key.pub)
 | 
			
		||||
					.previous (previous)
 | 
			
		||||
					.representative (nano::dev::genesis_key.pub)
 | 
			
		||||
					.balance (balance)
 | 
			
		||||
					.link (key.pub)
 | 
			
		||||
					.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
 | 
			
		||||
					.work (*system.work.generate (previous))
 | 
			
		||||
					.build ();
 | 
			
		||||
 | 
			
		||||
		node1->process_active (send);
 | 
			
		||||
		previous = send->hash ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ASSERT_TIMELY_EQ (5s, future1.wait_for (0s), std::future_status::ready);
 | 
			
		||||
 | 
			
		||||
	auto response1 = future1.get ();
 | 
			
		||||
	ASSERT_TRUE (response1);
 | 
			
		||||
	boost::property_tree::ptree event;
 | 
			
		||||
	std::stringstream stream;
 | 
			
		||||
	stream << response1.get ();
 | 
			
		||||
	boost::property_tree::read_json (stream, event);
 | 
			
		||||
	ASSERT_EQ (event.get<std::string> ("topic"), "confirmation");
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		boost::property_tree::ptree block_content = event.get_child ("message.block");
 | 
			
		||||
		// Check if linked_account is present
 | 
			
		||||
		ASSERT_EQ (1, block_content.count ("linked_account"));
 | 
			
		||||
		// Make sure linked_account is non-zero.
 | 
			
		||||
		ASSERT_NE ("0", block_content.get<std::string> ("linked_account"));
 | 
			
		||||
	}
 | 
			
		||||
	catch (std::runtime_error const & ex)
 | 
			
		||||
	{
 | 
			
		||||
		FAIL () << ex.what ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ack_ready = false;
 | 
			
		||||
	auto task2 = ([&ack_ready, config, &node1] () {
 | 
			
		||||
		fake_websocket_client client (node1->websocket.server->listening_port ());
 | 
			
		||||
		client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {"confirmation_type": "active_quorum", "include_block": "true", "include_linked_account": "true"}})json");
 | 
			
		||||
		client.await_ack ();
 | 
			
		||||
		ack_ready = true;
 | 
			
		||||
		EXPECT_EQ (1, node1->websocket.server->subscriber_count (nano::websocket::topic::confirmation));
 | 
			
		||||
		return client.get_response ();
 | 
			
		||||
	});
 | 
			
		||||
	auto future2 = std::async (std::launch::async, task2);
 | 
			
		||||
 | 
			
		||||
	ASSERT_TIMELY (10s, ack_ready);
 | 
			
		||||
 | 
			
		||||
	// Quick-confirm a receive block
 | 
			
		||||
	{
 | 
			
		||||
		nano::state_block_builder builder;
 | 
			
		||||
		balance = send_amount;
 | 
			
		||||
		auto open = builder
 | 
			
		||||
					.account (key.pub)
 | 
			
		||||
					.previous (0)
 | 
			
		||||
					.representative (nano::dev::genesis_key.pub)
 | 
			
		||||
					.balance (balance)
 | 
			
		||||
					.link (previous)
 | 
			
		||||
					.sign (key.prv, key.pub)
 | 
			
		||||
					.work (*system.work.generate (key.pub))
 | 
			
		||||
					.build ();
 | 
			
		||||
 | 
			
		||||
		node1->process_active (open);
 | 
			
		||||
		previous = open->hash ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ASSERT_TIMELY_EQ (5s, future2.wait_for (0s), std::future_status::ready);
 | 
			
		||||
 | 
			
		||||
	auto response2 = future2.get ();
 | 
			
		||||
	ASSERT_TRUE (response2);
 | 
			
		||||
	boost::property_tree::ptree event2;
 | 
			
		||||
	std::stringstream stream2;
 | 
			
		||||
	stream2 << response2.get ();
 | 
			
		||||
	boost::property_tree::read_json (stream2, event2);
 | 
			
		||||
	ASSERT_EQ (event2.get<std::string> ("topic"), "confirmation");
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		boost::property_tree::ptree block_content = event2.get_child ("message.block");
 | 
			
		||||
		// Check if linked_account is present
 | 
			
		||||
		ASSERT_EQ (1, block_content.count ("linked_account"));
 | 
			
		||||
		// Make sure linked_account is non-zero.
 | 
			
		||||
		ASSERT_NE ("0", block_content.get<std::string> ("linked_account"));
 | 
			
		||||
	}
 | 
			
		||||
	catch (std::runtime_error const & ex)
 | 
			
		||||
	{
 | 
			
		||||
		FAIL () << ex.what ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ack_ready = false;
 | 
			
		||||
	auto task3 = ([&ack_ready, config, &node1] () {
 | 
			
		||||
		fake_websocket_client client (node1->websocket.server->listening_port ());
 | 
			
		||||
		client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {"confirmation_type": "active_quorum", "include_block": "true", "include_linked_account": "true"}})json");
 | 
			
		||||
		client.await_ack ();
 | 
			
		||||
		ack_ready = true;
 | 
			
		||||
		EXPECT_EQ (1, node1->websocket.server->subscriber_count (nano::websocket::topic::confirmation));
 | 
			
		||||
		return client.get_response ();
 | 
			
		||||
	});
 | 
			
		||||
	auto future3 = std::async (std::launch::async, task3);
 | 
			
		||||
 | 
			
		||||
	ASSERT_TIMELY (10s, ack_ready);
 | 
			
		||||
 | 
			
		||||
	// Quick-confirm a change block
 | 
			
		||||
	{
 | 
			
		||||
		nano::state_block_builder builder;
 | 
			
		||||
		auto change = builder
 | 
			
		||||
					  .account (key.pub)
 | 
			
		||||
					  .previous (previous)
 | 
			
		||||
					  .representative (key.pub)
 | 
			
		||||
					  .balance (balance)
 | 
			
		||||
					  .link (0)
 | 
			
		||||
					  .sign (key.prv, key.pub)
 | 
			
		||||
					  .work (*system.work.generate (previous))
 | 
			
		||||
					  .build ();
 | 
			
		||||
 | 
			
		||||
		node1->process_active (change);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ASSERT_TIMELY_EQ (5s, future3.wait_for (0s), std::future_status::ready);
 | 
			
		||||
 | 
			
		||||
	auto response3 = future3.get ();
 | 
			
		||||
	ASSERT_TRUE (response3);
 | 
			
		||||
	boost::property_tree::ptree event3;
 | 
			
		||||
	std::stringstream stream3;
 | 
			
		||||
	stream3 << response3.get ();
 | 
			
		||||
	boost::property_tree::read_json (stream3, event3);
 | 
			
		||||
	ASSERT_EQ (event3.get<std::string> ("topic"), "confirmation");
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		boost::property_tree::ptree block_content = event3.get_child ("message.block");
 | 
			
		||||
		// Check if linked_account is present
 | 
			
		||||
		ASSERT_EQ (1, block_content.count ("linked_account"));
 | 
			
		||||
		// Make sure linked_account is zero.
 | 
			
		||||
		ASSERT_EQ ("0", block_content.get<std::string> ("linked_account"));
 | 
			
		||||
	}
 | 
			
		||||
	catch (std::runtime_error const & ex)
 | 
			
		||||
	{
 | 
			
		||||
		FAIL () << ex.what ();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST (websocket, confirmation_options_sideband)
 | 
			
		||||
{
 | 
			
		||||
	nano::test::system system;
 | 
			
		||||
| 
						 | 
				
			
			@ -681,7 +852,7 @@ TEST (websocket, vote_options_type)
 | 
			
		|||
 | 
			
		||||
	// Custom made votes for simplicity
 | 
			
		||||
	auto vote = nano::test::make_vote (nano::dev::genesis_key, { nano::dev::genesis }, 0, 0);
 | 
			
		||||
	nano::websocket::message_builder builder;
 | 
			
		||||
	nano::websocket::message_builder builder{ node1->ledger };
 | 
			
		||||
	auto msg (builder.vote_received (vote, nano::vote_code::replay));
 | 
			
		||||
	node1->websocket.server->broadcast (msg);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ nano::distributed_work::~distributed_work ()
 | 
			
		|||
	{
 | 
			
		||||
		if (!node_l->stopped && node_l->websocket.server && node_l->websocket.server->any_subscriber (nano::websocket::topic::work))
 | 
			
		||||
		{
 | 
			
		||||
			nano::websocket::message_builder builder;
 | 
			
		||||
			nano::websocket::message_builder builder{ node_l->ledger };
 | 
			
		||||
			if (status == work_generation_status::success)
 | 
			
		||||
			{
 | 
			
		||||
				node_l->websocket.server->broadcast (builder.work_generation (request.version, request.root.as_block_hash (), work_result, request.difficulty, node_l->default_difficulty (request.version), elapsed.value (), winner, bad_peers));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -187,7 +187,7 @@ nano::node::node (std::shared_ptr<boost::asio::io_context> io_ctx_a, std::filesy
 | 
			
		|||
	bootstrap_server{ *bootstrap_server_impl },
 | 
			
		||||
	bootstrap_impl{ std::make_unique<nano::bootstrap_service> (config, ledger, ledger_notifications, block_processor, network, stats, logger) },
 | 
			
		||||
	bootstrap{ *bootstrap_impl },
 | 
			
		||||
	websocket_impl{ std::make_unique<nano::websocket_server> (config.websocket_config, observers, wallets, ledger, io_ctx, logger) },
 | 
			
		||||
	websocket_impl{ std::make_unique<nano::websocket_server> (config.websocket_config, *this, observers, wallets, ledger, io_ctx, logger) },
 | 
			
		||||
	websocket{ *websocket_impl },
 | 
			
		||||
	epoch_upgrader_impl{ std::make_unique<nano::epoch_upgrader> (*this, ledger, store, network_params, logger) },
 | 
			
		||||
	epoch_upgrader{ *epoch_upgrader_impl },
 | 
			
		||||
| 
						 | 
				
			
			@ -236,7 +236,7 @@ nano::node::node (std::shared_ptr<boost::asio::io_context> io_ctx_a, std::filesy
 | 
			
		|||
			{
 | 
			
		||||
				if (websocket.server && websocket.server->any_subscriber (nano::websocket::topic::new_unconfirmed_block))
 | 
			
		||||
				{
 | 
			
		||||
					websocket.server->broadcast (nano::websocket::message_builder ().new_block_arrived (*context.block));
 | 
			
		||||
					websocket.server->broadcast (nano::websocket::message_builder (ledger).new_block_arrived (*context.block));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
#include <nano/lib/logging.hpp>
 | 
			
		||||
#include <nano/lib/work.hpp>
 | 
			
		||||
#include <nano/node/election_status.hpp>
 | 
			
		||||
#include <nano/node/node.hpp>
 | 
			
		||||
#include <nano/node/node_observers.hpp>
 | 
			
		||||
#include <nano/node/transport/channel.hpp>
 | 
			
		||||
#include <nano/node/vote_router.hpp>
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +36,7 @@ nano::websocket::confirmation_options::confirmation_options (boost::property_tre
 | 
			
		|||
	include_block = options_a.get<bool> ("include_block", true);
 | 
			
		||||
	include_election_info = options_a.get<bool> ("include_election_info", false);
 | 
			
		||||
	include_election_info_with_votes = options_a.get<bool> ("include_election_info_with_votes", false);
 | 
			
		||||
	include_linked_account = options_a.get<bool> ("include_linked_account", false);
 | 
			
		||||
	include_sideband_info = options_a.get<bool> ("include_sideband_info", false);
 | 
			
		||||
 | 
			
		||||
	confirmation_types = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +99,14 @@ nano::websocket::confirmation_options::confirmation_options (boost::property_tre
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
	check_filter_empty ();
 | 
			
		||||
 | 
			
		||||
	if (include_linked_account)
 | 
			
		||||
	{
 | 
			
		||||
		if (!include_block)
 | 
			
		||||
		{
 | 
			
		||||
			logger.warn (nano::log::type::websocket, "The option \"include_linked_account\" requires \"include_block\" to be set to true, as linked accounts are only retrieved when block content is included");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool nano::websocket::confirmation_options::should_filter (nano::websocket::message const & message_a) const
 | 
			
		||||
| 
						 | 
				
			
			@ -580,8 +590,9 @@ void nano::websocket::listener::stop ()
 | 
			
		|||
	sessions.clear ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nano::websocket::listener::listener (nano::logger & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) :
 | 
			
		||||
nano::websocket::listener::listener (nano::logger & logger_a, nano::node & node_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) :
 | 
			
		||||
	logger (logger_a),
 | 
			
		||||
	node (node_a),
 | 
			
		||||
	wallets (wallets_a),
 | 
			
		||||
	acceptor (io_ctx_a),
 | 
			
		||||
	socket (io_ctx_a)
 | 
			
		||||
| 
						 | 
				
			
			@ -650,7 +661,7 @@ void nano::websocket::listener::on_accept (boost::system::error_code ec)
 | 
			
		|||
 | 
			
		||||
void nano::websocket::listener::broadcast_confirmation (std::shared_ptr<nano::block> const & block_a, nano::account const & account_a, nano::amount const & amount_a, std::string const & subtype, nano::election_status const & election_status_a, std::vector<nano::vote_with_weight_info> const & election_votes_a)
 | 
			
		||||
{
 | 
			
		||||
	nano::websocket::message_builder builder;
 | 
			
		||||
	nano::websocket::message_builder builder{ node.ledger };
 | 
			
		||||
 | 
			
		||||
	nano::lock_guard<nano::mutex> lk (sessions_mutex);
 | 
			
		||||
	boost::optional<nano::websocket::message> msg_with_block;
 | 
			
		||||
| 
						 | 
				
			
			@ -711,6 +722,11 @@ void nano::websocket::listener::decrease_subscriber_count (nano::websocket::topi
 | 
			
		|||
	count -= 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nano::websocket::message_builder::message_builder (nano::ledger & ledger) :
 | 
			
		||||
	ledger{ ledger }
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
| 
						 | 
				
			
			@ -794,6 +810,18 @@ nano::websocket::message nano::websocket::message_builder::block_confirmed (std:
 | 
			
		|||
	{
 | 
			
		||||
		boost::property_tree::ptree block_node_l;
 | 
			
		||||
		block_a->serialize_json (block_node_l);
 | 
			
		||||
		if (options_a.get_include_linked_account ())
 | 
			
		||||
		{
 | 
			
		||||
			auto linked_account = ledger.linked_account (ledger.tx_begin_read (), *block_a);
 | 
			
		||||
			if (linked_account.has_value ())
 | 
			
		||||
			{
 | 
			
		||||
				block_node_l.add ("linked_account", linked_account.value ().to_account ());
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				block_node_l.add ("linked_account", "0");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!subtype.empty ())
 | 
			
		||||
		{
 | 
			
		||||
			block_node_l.add ("subtype", subtype);
 | 
			
		||||
| 
						 | 
				
			
			@ -985,7 +1013,7 @@ std::string nano::websocket::message::to_string () const
 | 
			
		|||
 * websocket_server
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
nano::websocket_server::websocket_server (nano::websocket::config & config_a, nano::node_observers & observers_a, nano::wallets & wallets_a, nano::ledger & ledger_a, boost::asio::io_context & io_ctx_a, nano::logger & logger_a) :
 | 
			
		||||
nano::websocket_server::websocket_server (nano::websocket::config & config_a, nano::node & node_a, nano::node_observers & observers_a, nano::wallets & wallets_a, nano::ledger & ledger_a, boost::asio::io_context & io_ctx_a, nano::logger & logger_a) :
 | 
			
		||||
	config{ config_a },
 | 
			
		||||
	observers{ observers_a },
 | 
			
		||||
	wallets{ wallets_a },
 | 
			
		||||
| 
						 | 
				
			
			@ -999,7 +1027,7 @@ nano::websocket_server::websocket_server (nano::websocket::config & config_a, na
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	auto endpoint = nano::tcp_endpoint{ boost::asio::ip::make_address_v6 (config.address), config.port };
 | 
			
		||||
	server = std::make_shared<nano::websocket::listener> (logger, wallets, io_ctx, endpoint);
 | 
			
		||||
	server = std::make_shared<nano::websocket::listener> (logger, node_a, wallets, io_ctx, endpoint);
 | 
			
		||||
 | 
			
		||||
	observers.blocks.add ([this] (nano::election_status const & status_a, std::vector<nano::vote_with_weight_info> const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a, bool is_state_epoch_a) {
 | 
			
		||||
		debug_assert (status_a.type != nano::election_status_type::ongoing);
 | 
			
		||||
| 
						 | 
				
			
			@ -1036,7 +1064,7 @@ nano::websocket_server::websocket_server (nano::websocket::config & config_a, na
 | 
			
		|||
	observers.active_started.add ([this] (nano::block_hash const & hash_a) {
 | 
			
		||||
		if (server->any_subscriber (nano::websocket::topic::started_election))
 | 
			
		||||
		{
 | 
			
		||||
			nano::websocket::message_builder builder;
 | 
			
		||||
			nano::websocket::message_builder builder{ ledger };
 | 
			
		||||
			server->broadcast (builder.started_election (hash_a));
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
| 
						 | 
				
			
			@ -1044,7 +1072,7 @@ nano::websocket_server::websocket_server (nano::websocket::config & config_a, na
 | 
			
		|||
	observers.active_stopped.add ([this] (nano::block_hash const & hash_a) {
 | 
			
		||||
		if (server->any_subscriber (nano::websocket::topic::stopped_election))
 | 
			
		||||
		{
 | 
			
		||||
			nano::websocket::message_builder builder;
 | 
			
		||||
			nano::websocket::message_builder builder{ ledger };
 | 
			
		||||
			server->broadcast (builder.stopped_election (hash_a));
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
| 
						 | 
				
			
			@ -1052,7 +1080,7 @@ nano::websocket_server::websocket_server (nano::websocket::config & config_a, na
 | 
			
		|||
	observers.telemetry.add ([this] (nano::telemetry_data const & telemetry_data, std::shared_ptr<nano::transport::channel> const & channel) {
 | 
			
		||||
		if (server->any_subscriber (nano::websocket::topic::telemetry))
 | 
			
		||||
		{
 | 
			
		||||
			nano::websocket::message_builder builder;
 | 
			
		||||
			nano::websocket::message_builder builder{ ledger };
 | 
			
		||||
			server->broadcast (builder.telemetry_received (telemetry_data, channel->get_remote_endpoint ()));
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
| 
						 | 
				
			
			@ -1061,7 +1089,7 @@ nano::websocket_server::websocket_server (nano::websocket::config & config_a, na
 | 
			
		|||
		debug_assert (vote_a != nullptr);
 | 
			
		||||
		if (server->any_subscriber (nano::websocket::topic::vote))
 | 
			
		||||
		{
 | 
			
		||||
			nano::websocket::message_builder builder;
 | 
			
		||||
			nano::websocket::message_builder builder{ ledger };
 | 
			
		||||
			auto msg{ builder.vote_received (vote_a, code_a) };
 | 
			
		||||
			server->broadcast (msg);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@ class election_status;
 | 
			
		|||
enum class election_status_type : uint8_t;
 | 
			
		||||
class ledger;
 | 
			
		||||
class logger;
 | 
			
		||||
class node;
 | 
			
		||||
class node_observers;
 | 
			
		||||
class telemetry_data;
 | 
			
		||||
class vote;
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +89,8 @@ namespace websocket
 | 
			
		|||
	class message_builder final
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		message_builder (nano::ledger & ledger);
 | 
			
		||||
 | 
			
		||||
		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);
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +106,8 @@ namespace websocket
 | 
			
		|||
	private:
 | 
			
		||||
		/** Set the common fields for messages: timestamp and topic. */
 | 
			
		||||
		void set_common_fields (message & message_a);
 | 
			
		||||
 | 
			
		||||
		nano::ledger & ledger;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/** Options for subscriptions */
 | 
			
		||||
| 
						 | 
				
			
			@ -183,6 +188,12 @@ namespace websocket
 | 
			
		|||
			return include_election_info_with_votes;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** Returns whether or not to include linked accounts */
 | 
			
		||||
		bool get_include_linked_account () const
 | 
			
		||||
		{
 | 
			
		||||
			return include_linked_account;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/** Returns whether or not to include sideband info */
 | 
			
		||||
		bool get_include_sideband_info () const
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +214,7 @@ namespace websocket
 | 
			
		|||
 | 
			
		||||
		bool include_election_info{ false };
 | 
			
		||||
		bool include_election_info_with_votes{ false };
 | 
			
		||||
		bool include_linked_account{ false };
 | 
			
		||||
		bool include_sideband_info{ false };
 | 
			
		||||
		bool include_block{ true };
 | 
			
		||||
		bool has_account_filtering_options{ false };
 | 
			
		||||
| 
						 | 
				
			
			@ -302,7 +314,7 @@ namespace websocket
 | 
			
		|||
	class listener final : public std::enable_shared_from_this<listener>
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		listener (nano::logger &, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a);
 | 
			
		||||
		listener (nano::logger &, nano::node &, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a);
 | 
			
		||||
 | 
			
		||||
		/** Start accepting connections */
 | 
			
		||||
		void run ();
 | 
			
		||||
| 
						 | 
				
			
			@ -352,6 +364,7 @@ namespace websocket
 | 
			
		|||
		void decrease_subscriber_count (nano::websocket::topic const & topic_a);
 | 
			
		||||
 | 
			
		||||
		nano::logger & logger;
 | 
			
		||||
		nano::node & node;
 | 
			
		||||
		nano::wallets & wallets;
 | 
			
		||||
		boost::asio::ip::tcp::acceptor acceptor;
 | 
			
		||||
		socket_type socket;
 | 
			
		||||
| 
						 | 
				
			
			@ -368,7 +381,7 @@ namespace websocket
 | 
			
		|||
class websocket_server
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	websocket_server (nano::websocket::config &, nano::node_observers &, nano::wallets &, nano::ledger &, boost::asio::io_context &, nano::logger &);
 | 
			
		||||
	websocket_server (nano::websocket::config &, nano::node &, nano::node_observers &, nano::wallets &, nano::ledger &, boost::asio::io_context &, nano::logger &);
 | 
			
		||||
 | 
			
		||||
	void start ();
 | 
			
		||||
	void stop ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1170,6 +1170,22 @@ std::shared_ptr<nano::block> nano::ledger::find_receive_block_by_send_hash (secu
 | 
			
		|||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::optional<nano::account> nano::ledger::linked_account (secure::transaction const & transaction, nano::block const & block)
 | 
			
		||||
{
 | 
			
		||||
	debug_assert (block.has_sideband ());
 | 
			
		||||
 | 
			
		||||
	if (block.sideband ().details.is_send)
 | 
			
		||||
	{
 | 
			
		||||
		return block.destination ();
 | 
			
		||||
	}
 | 
			
		||||
	else if (block.sideband ().details.is_receive)
 | 
			
		||||
	{
 | 
			
		||||
		return any.block_account (transaction, block.source ());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return std::nullopt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nano::account const & nano::ledger::epoch_signer (nano::link const & link_a) const
 | 
			
		||||
{
 | 
			
		||||
	return constants.epochs.signer (constants.epochs.epoch (link_a));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,7 @@ public:
 | 
			
		|||
	bool is_epoch_link (nano::link const &) const;
 | 
			
		||||
	std::array<nano::block_hash, 2> dependent_blocks (secure::transaction const &, nano::block const &) const;
 | 
			
		||||
	std::shared_ptr<nano::block> find_receive_block_by_send_hash (secure::transaction const &, nano::account const & destination, nano::block_hash const & send_block_hash);
 | 
			
		||||
	std::optional<nano::account> linked_account (secure::transaction const &, nano::block const &);
 | 
			
		||||
	nano::account const & epoch_signer (nano::link const &) const;
 | 
			
		||||
	nano::link const & epoch_link (nano::epoch) const;
 | 
			
		||||
	bool migrate_lmdb_to_rocksdb (std::filesystem::path const &) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue