diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index 6ff3ba03..3e01d2df 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -382,6 +382,75 @@ TEST (websocket, confirmation_options_votes) } } +TEST (websocket, confirmation_options_sideband) +{ + 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 ack_ready{ false }; + auto task1 = ([&ack_ready, config, &node1] () { + fake_websocket_client client (config.websocket_config.port); + client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {"confirmation_type": "active_quorum", "include_block": "false", "include_sideband_info": "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_shared (); + + node1->process_active (send); + previous = send->hash (); + } + + ASSERT_TIMELY (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 ("topic"), "confirmation"); + try + { + boost::property_tree::ptree sideband_info = event.get_child ("message.sideband"); + // Check if height and local_timestamp are present + ASSERT_EQ (1, sideband_info.count ("height")); + ASSERT_EQ (1, sideband_info.count ("local_timestamp")); + // Make sure height and local_timestamp are non-zero. + ASSERT_NE ("0", sideband_info.get ("height")); + ASSERT_NE ("0", sideband_info.get ("local_timestamp")); + } + catch (std::runtime_error const & ex) + { + FAIL () << ex.what (); + } +} + // Tests updating options of block confirmations TEST (websocket, confirmation_options_update) { diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index 505a5ca9..67b057ac 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -26,6 +26,7 @@ nano::websocket::confirmation_options::confirmation_options (boost::property_tre include_block = options_a.get ("include_block", true); include_election_info = options_a.get ("include_election_info", false); include_election_info_with_votes = options_a.get ("include_election_info_with_votes", false); + include_sideband_info = options_a.get ("include_sideband_info", false); confirmation_types = 0; auto type_l (options_a.get ("confirmation_type", "all")); @@ -766,6 +767,14 @@ nano::websocket::message nano::websocket::message_builder::block_confirmed (std: message_node_l.add_child ("block", block_node_l); } + if (options_a.get_include_sideband_info ()) + { + boost::property_tree::ptree sideband_node_l; + sideband_node_l.add ("height", std::to_string (block_a->sideband ().height)); + sideband_node_l.add ("local_timestamp", std::to_string (block_a->sideband ().timestamp)); + message_node_l.add_child ("sideband", sideband_node_l); + } + message_l.contents.add_child ("message", message_node_l); return message_l; diff --git a/nano/node/websocket.hpp b/nano/node/websocket.hpp index 88e60eed..264a9f94 100644 --- a/nano/node/websocket.hpp +++ b/nano/node/websocket.hpp @@ -174,6 +174,12 @@ namespace websocket return include_election_info_with_votes; } + /** Returns whether or not to include sideband info */ + bool get_include_sideband_info () const + { + return include_sideband_info; + } + static constexpr uint8_t const type_active_quorum = 1; static constexpr uint8_t const type_active_confirmation_height = 2; static constexpr uint8_t const type_inactive = 4; @@ -187,6 +193,7 @@ namespace websocket boost::optional logger; bool include_election_info{ false }; bool include_election_info_with_votes{ false }; + bool include_sideband_info{ false }; bool include_block{ true }; bool has_account_filtering_options{ false }; bool all_local_accounts{ false };