84 std::unique_ptr<ringbuffer::Circuit> circuit_,
85 std::unique_ptr<ringbuffer::WriterFactory> basic_writer_factory_,
86 std::unique_ptr<oversized::WriterFactory> writer_factory_,
88 size_t sig_tx_interval,
89 size_t sig_ms_interval,
92 circuit(
std::move(circuit_)),
93 basic_writer_factory(
std::move(basic_writer_factory_)),
94 writer_factory(
std::move(writer_factory_)),
95 ringbuffer_logger(ringbuffer_logger_),
98 rpcsessions(
std::make_shared<
RPCSessions>(*writer_factory, rpc_map))
100 ccf::pal::initialize_enclave();
108#if !(defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3)
112 ENGINE_load_rdrand() != 1 ||
113 (rdrand_engine = ENGINE_by_id(
"rdrand")) ==
nullptr ||
114 ENGINE_init(rdrand_engine) != 1 ||
115 ENGINE_set_default(rdrand_engine, ENGINE_METHOD_RAND) != 1)
118 ENGINE_free(rdrand_engine);
120 "could not initialize RDRAND engine for OpenSSL");
124 to_host = writer_factory->create_writer_to_outside();
130 node = std::make_unique<ccf::NodeState>(
131 *writer_factory, network, rpcsessions, curve_id);
134 context = std::make_unique<NodeContext>(node->get_node_id());
137 historical_state_cache = std::make_shared<ccf::historical::StateCache>(
140 writer_factory->create_writer_to_outside());
141 context->install_subsystem(historical_state_cache);
143 indexer = std::make_shared<ccf::indexing::Indexer>(
144 std::make_shared<ccf::indexing::HistoricalTransactionFetcher>(
145 historical_state_cache));
146 context->install_subsystem(indexer);
148 lfs_access = std::make_shared<ccf::indexing::EnclaveLFSAccess>(
149 writer_factory->create_writer_to_outside());
150 context->install_subsystem(lfs_access);
152 context->install_subsystem(std::make_shared<ccf::HostProcesses>(*node));
153 context->install_subsystem(std::make_shared<ccf::NodeOperation>(*node));
154 context->install_subsystem(
155 std::make_shared<ccf::GovernanceEffects>(*node));
157 context->install_subsystem(
158 std::make_shared<ccf::NetworkIdentitySubsystem>(
161 context->install_subsystem(
162 std::make_shared<ccf::NodeConfigurationSubsystem>(*node));
164 context->install_subsystem(std::make_shared<ccf::ACMESubsystem>(*node));
166 auto cpss = std::make_shared<ccf::CustomProtocolSubsystem>(*node);
167 context->install_subsystem(cpss);
168 rpcsessions->set_custom_protocol_subsystem(cpss);
170 static constexpr size_t max_interpreter_cache_size = 10;
171 auto interpreter_cache =
172 std::make_shared<ccf::js::InterpreterCache>(max_interpreter_cache_size);
173 context->install_subsystem(interpreter_cache);
177 std::make_unique<ccf::MemberRpcFrontend>(network, *context));
180 std::make_unique<ccf::UserRpcFrontend>(
184 std::make_unique<ccf::NodeRpcFrontend>(network, *context));
190 std::make_unique<ccf::ACMERpcFrontend>(network, *context));
303#ifndef VIRTUAL_ENCLAVE
315 bp, AdminMessage::stop, [&bp](
const uint8_t*,
size_t) {
321 bp, AdminMessage::stop_notice, [
this](
const uint8_t*,
size_t) {
325 last_tick_time = ccf::get_enclave_time();
331 const auto message_counts = disp.retrieve_message_counts();
332 const auto j = disp.convert_message_counts(message_counts);
333 RINGBUFFER_WRITE_MESSAGE(
334 AdminMessage::work_stats, to_host, j.dump());
336 const auto time_now = ccf::get_enclave_time();
337 ringbuffer_logger->set_time(time_now);
339 const auto elapsed_ms =
340 std::chrono::duration_cast<std::chrono::milliseconds>(
341 time_now - last_tick_time);
342 if (elapsed_ms.count() > 0)
344 last_tick_time += elapsed_ms;
346 node->tick(elapsed_ms);
347 historical_state_cache->tick(elapsed_ms);
348 ::threading::ThreadMessaging::instance().tick(elapsed_ms);
351 if (!node->is_reading_public_ledger())
353 for (auto& [actor, frontend] : rpc_map->frontends())
355 frontend->tick(elapsed_ms);
363 bp, ccf::node_inbound, [
this](
const uint8_t* data,
size_t size) {
366 node->recv_node_inbound(data, size);
368 catch (
const std::exception& e)
371 "Ignoring node_inbound message due to exception: {}", e.what());
377 ::consensus::ledger_entry_range,
378 [
this](
const uint8_t* data,
size_t size) {
379 const auto [from_seqno, to_seqno, purpose, body] =
380 ringbuffer::read_message<::consensus::ledger_entry_range>(
384 case ::consensus::LedgerRequestPurpose::Recovery:
386 if (node->is_reading_public_ledger())
388 node->recover_public_ledger_entries(body);
390 else if (node->is_reading_private_ledger())
392 node->recover_private_ledger_entries(body);
396 auto [s, _, __] = node->state();
398 "Cannot recover ledger entry: Unexpected node state {}", s);
402 case ::consensus::LedgerRequestPurpose::HistoricalQuery:
404 historical_state_cache->handle_ledger_entries(
405 from_seqno, to_seqno, body);
417 ::consensus::ledger_no_entry_range,
418 [
this](
const uint8_t* data,
size_t size) {
419 const auto [from_seqno, to_seqno, purpose] =
420 ringbuffer::read_message<::consensus::ledger_no_entry_range>(
424 case ::consensus::LedgerRequestPurpose::Recovery:
426 node->recover_ledger_end();
429 case ::consensus::LedgerRequestPurpose::HistoricalQuery:
431 historical_state_cache->handle_no_entry_range(
432 from_seqno, to_seqno);
444 ::consensus::snapshot_allocated,
445 [
this](
const uint8_t* data,
size_t size) {
446 const auto [snapshot_span, generation_count] =
447 ringbuffer::read_message<::consensus::snapshot_allocated>(
450 node->write_snapshot(snapshot_span, generation_count);
453 rpcsessions->register_message_handlers(bp.get_dispatcher());
457 static constexpr size_t max_messages = 256;
459 size_t consecutive_idles = 0u;
460 while (!bp.get_finished())
463 auto read = bp.read_n(max_messages, circuit->read_from_outside());
466 size_t thread_msg = 0;
467 while (thread_msg < max_messages &&
475 if (read == 0 && thread_msg == 0)
477 const auto time_now = ccf::get_enclave_time();
478 static std::chrono::microseconds idling_start_time;
480 if (consecutive_idles == 0)
482 idling_start_time = time_now;
486 constexpr std::chrono::milliseconds timeout(5);
487 if ((time_now - idling_start_time) > timeout)
489 std::this_thread::sleep_for(timeout * 10);
501 consecutive_idles = 0;
505 LOG_INFO_FMT(
"Enclave stopped successfully. Stopping host...");
512#ifndef VIRTUAL_ENCLAVE
513 catch (
const std::exception& e)
519 AdminMessage::fatal_error_msg, to_host, std::string(e.what()));