15 uint32_t watchtower_id,
17 const std::shared_ptr<logging::log>& log)
18 : m_watchtower_id(watchtower_id),
19 m_opts(std::move(opts)),
21 m_watchtower(m_opts.m_watchtower_block_cache_size,
22 m_opts.m_watchtower_error_cache_size),
23 m_archiver_client(m_opts.m_archiver_endpoints[0], log) {}
26 m_internal_network.close();
27 m_external_network.close();
28 m_atomizer_network.close();
30 if(m_internal_server.joinable()) {
31 m_internal_server.join();
34 if(m_external_server.joinable()) {
35 m_external_server.join();
38 if(m_atomizer_thread.joinable()) {
39 m_atomizer_thread.join();
44 auto internal = m_internal_network.start_server(
45 m_opts.m_watchtower_internal_endpoints[m_watchtower_id],
47 return internal_server_handler(std::forward<decltype(pkt)>(pkt));
50 if(!internal.has_value()) {
51 m_logger->error(
"Failed to establish watchtower internal server.");
55 m_internal_server = std::move(internal.value());
57 auto external = m_external_network.start_server(
58 m_opts.m_watchtower_client_endpoints[m_watchtower_id],
60 return external_server_handler(std::forward<decltype(pkt)>(pkt));
63 if(!external.has_value()) {
64 m_logger->error(
"Failed to establish watchtower external server.");
68 m_external_server = std::move(external.value());
70 static constexpr auto retry_delay = std::chrono::seconds(1);
71 m_atomizer_network.cluster_connect(m_opts.m_atomizer_endpoints,
false);
72 while(!m_atomizer_network.connected_to_one()) {
76 m_logger->warn(
"Failed to connect to any atomizers, waiting...");
77 std::this_thread::sleep_for(retry_delay);
80 while(!m_archiver_client.init()) {
81 m_logger->warn(
"Failed to connect to archiver, retrying...");
82 std::this_thread::sleep_for(retry_delay);
85 m_atomizer_thread = m_atomizer_network.start_handler([&](
auto&& pkt) {
86 return atomizer_handler(std::forward<
decltype(pkt)>(pkt));
89 m_logger->info(
"Connected to atomizers.");
94auto cbdc::watchtower::controller::atomizer_handler(
97 if(!maybe_blk.has_value()) {
98 m_logger->error(
"Invalid block packet");
101 auto& blk = maybe_blk.value();
102 m_logger->debug(
"Received block",
105 blk.m_transactions.size(),
107 if(blk.m_height != (m_last_blk_height + 1)) {
108 m_logger->warn(
"Block not contiguous. Last block:", m_last_blk_height);
109 while(blk.m_height != (m_last_blk_height + 1)) {
111 = m_archiver_client.get_block(m_last_blk_height + 1);
113 m_logger->warn(
"Waiting for archiver sync");
114 static constexpr auto archiver_wait_time
115 = std::chrono::milliseconds(100);
116 std::this_thread::sleep_for(archiver_wait_time);
120 m_last_blk_height = (*missed_blk).m_height;
121 m_watchtower.add_block(std::move(*missed_blk));
124 m_last_blk_height = blk.m_height;
125 m_watchtower.add_block(std::move(blk));
129auto cbdc::watchtower::controller::internal_server_handler(
133 if(!maybe_errs.has_value()) {
134 m_logger->error(
"Invalid internal request packet");
137 m_watchtower.add_errors(std::move(maybe_errs.value()));
141auto cbdc::watchtower::controller::external_server_handler(
148 auto res = m_watchtower.handle_status_update_request(su_req);
149 m_logger->info(
"Received status_update_request with",
150 su_req.uhs_ids().size(),
156 auto res = m_watchtower.handle_best_block_height_request(bbh_req);
157 m_logger->info(
"Received request_best_block_height from peer",
161 auto msg = std::visit(res_handler, req.payload());
166 return m_last_blk_height;
Serializer implementation for buffer.
Buffer to store and retrieve byte data.
auto init() -> bool
Initializes the controller.
auto get_block_height() const -> uint64_t
Network request to interact with the Watchtower's status update service.
exec_request request
Agent RPC request type.
overloaded(Ts...) -> overloaded< Ts... >
auto from_buffer(nuraft::buffer &buf) -> std::optional< T >
Deserialize object of given type from a nuraft::buffer.
auto make_buffer(const T &obj) -> std::enable_if_t< std::is_same_v< B, nuraft::ptr< nuraft::buffer > >, nuraft::ptr< nuraft::buffer > >
Serialize object into nuraft::buffer using a cbdc::nuraft_serializer.
Project-wide configuration options.
Request the watchtower's known best block height.