56#ifdef USE_NULL_ENCRYPTOR
57# include "kv/test/null_encryptor.h"
63#define FMT_HEADER_ONLY
64#include <fmt/format.h>
65#include <nlohmann/json.hpp>
67#include <unordered_set>
97 std::vector<ccf::crypto::SubjectAltName> subject_alt_names;
99 std::shared_ptr<ccf::crypto::ECKeyPair_OpenSSL> node_sign_kp;
101 std::shared_ptr<ccf::crypto::RSAKeyPair> node_encrypt_kp;
103 std::optional<ccf::crypto::Pem> endorsed_node_cert = std::nullopt;
106 std::optional<pal::snp::TcbVersionRaw> snp_tcb_version = std::nullopt;
108 std::optional<pal::UVMEndorsements> snp_uvm_endorsements = std::nullopt;
109 std::vector<uint8_t> startup_snapshot;
110 std::shared_ptr<QuoteEndorsementsClient> quote_endorsements_client =
113 std::atomic<bool> stop_noticed =
false;
121 size_t sig_tx_interval = 0;
122 size_t sig_ms_interval = 0;
126 std::shared_ptr<ccf::kv::Consensus>
consensus;
127 std::shared_ptr<RPCMap> rpc_map;
128 std::shared_ptr<indexing::Indexer> indexer;
129 std::shared_ptr<NodeToNode> n2n_channels;
130 std::shared_ptr<Forwarder<NodeToNode>> cmd_forwarder;
131 std::shared_ptr<RPCSessions> rpcsessions;
133 std::shared_ptr<ccf::kv::TxHistory> history;
134 std::shared_ptr<ccf::kv::AbstractTxEncryptor> encryptor;
137 std::shared_ptr<Snapshotter> snapshotter;
142 std::shared_ptr<ccf::kv::Store> recovery_store;
146 std::vector<ccf::kv::Version> view_history;
150 static const size_t recovery_batch_size = 100;
155 std::shared_ptr<JwtKeyAutoRefresh> jwt_key_auto_refresh;
157 std::unique_ptr<StartupSnapshotInfo> startup_snapshot_info =
nullptr;
164 std::shared_ptr<ccf::kv::AbstractTxEncryptor> make_encryptor()
166#ifdef USE_NULL_ENCRYPTOR
167 return std::make_shared<ccf::kv::NullTxEncryptor>();
174 void initialise_startup_snapshot(
bool recovery =
false)
176 std::shared_ptr<ccf::kv::Store> snapshot_store;
181 auto snapshot_history = std::make_shared<MerkleTxHistory>(
189 auto snapshot_encryptor = make_encryptor();
191 snapshot_store->set_history(snapshot_history);
192 snapshot_store->set_encryptor(snapshot_encryptor);
196 snapshot_store = network.
tables;
200 startup_snapshot_info = initialise_from_snapshot(
202 std::move(startup_snapshot),
208 startup_seqno = startup_snapshot_info->seqno;
209 last_recovered_idx = startup_seqno;
210 last_recovered_signed_idx = last_recovered_idx;
217 std::shared_ptr<RPCSessions> rpcsessions,
223 node_encrypt_kp(
ccf::crypto::make_rsa_key_pair()),
224 writer_factory(writer_factory),
225 to_host(writer_factory.create_writer_to_outside()),
227 rpcsessions(
std::move(rpcsessions)),
228 share_manager(network.ledger_secrets)
234 const std::vector<uint8_t>& expected_node_public_key_der,
238 tx, quote_info_, expected_node_public_key_der, measurement);
246 std::shared_ptr<RPCMap> rpc_map_,
247 std::shared_ptr<AbstractRPCResponder> rpc_sessions_,
248 std::shared_ptr<indexing::Indexer> indexer_,
249 size_t sig_tx_interval_,
250 size_t sig_ms_interval_)
252 std::lock_guard<pal::Mutex> guard(lock);
255 consensus_config = consensus_config_;
258 sig_tx_interval = sig_tx_interval_;
259 sig_ms_interval = sig_ms_interval_;
261 n2n_channels = std::make_shared<NodeToNodeChannelManager>(writer_factory);
263 cmd_forwarder = std::make_shared<Forwarder<NodeToNode>>(
264 rpc_sessions_, n2n_channels, rpc_map);
268 for (
auto& [actor, fe] : rpc_map->frontends())
270 fe->set_sig_intervals(sig_tx_interval, sig_ms_interval);
271 fe->set_cmd_forwarder(cmd_forwarder);
281 if (measurement.has_value())
283 node_measurement = measurement.value();
287 throw std::logic_error(
"Failed to extract code id from quote");
290 auto snp_attestation =
292 if (snp_attestation.has_value())
294 snp_tcb_version = snp_attestation.value().reported_tcb;
301 "Security policy not set, skipping check against attestation host "
307 if (!quoted_digest.has_value())
309 throw std::logic_error(
"Unable to find host data in attestation");
312 auto const& security_policy =
315 auto security_policy_digest =
319 if (security_policy_digest != quoted_digest.value())
321 throw std::logic_error(fmt::format(
322 "Digest of decoded security policy \"{}\" {} does not match "
323 "attestation host data {}",
325 security_policy_digest.hex_str(),
326 quoted_digest.value().hex_str()));
329 "Successfully verified attested security policy {}",
330 security_policy_digest);
338 "UVM endorsements not set, skipping check against attestation "
354 uvm_endorsements_raw, node_measurement);
357 "Successfully verified attested UVM endorsements: {}",
358 snp_uvm_endorsements->to_str());
360 catch (
const std::exception& e)
362 throw std::logic_error(
363 fmt::format(
"Error verifying UVM endorsements: {}", e.what()));
372 create_and_send_boot_request(
373 aft::starting_view_change,
true );
378 if (!startup_snapshot.empty())
380 initialise_startup_snapshot();
389 setup_recovery_hook();
390 if (!startup_snapshot.empty())
392 initialise_startup_snapshot(
true);
393 snapshotter->set_last_snapshot_idx(last_recovered_idx);
402 throw std::logic_error(
403 fmt::format(
"Node was launched in unknown mode {}", start_type));
410 auto fetch_endorsements = [
this](
413 EndorsementEndpointsConfiguration&
417 this->quote_info = qi;
423 "Initial node attestation ({}): {}", jq.dump(), b64encoded_quote);
435 const auto j = nlohmann::json::parse(raw_data);
436 const auto aci_endorsements =
443 quote_info.
quote.data());
444 const auto reported_tcb = quote->reported_tcb;
448 const auto* tcb_begin =
449 reinterpret_cast<const uint8_t*
>(&reported_tcb);
450 const std::span<const uint8_t> tcb_bytes{
451 tcb_begin, tcb_begin +
sizeof(reported_tcb)};
452 auto tcb_as_hex = fmt::format(
453 "{:02x}", fmt::join(tcb_bytes.rbegin(), tcb_bytes.rend(),
""));
454 ccf::nonstd::to_upper(tcb_as_hex);
456 if (tcb_as_hex == aci_endorsements.tcbm)
459 "Using SNP endorsements loaded from file, endorsing TCB {}",
463 endorsements_pem.insert(
464 endorsements_pem.end(),
465 aci_endorsements.vcek_cert.begin(),
466 aci_endorsements.vcek_cert.end());
467 endorsements_pem.insert(
468 endorsements_pem.end(),
469 aci_endorsements.certificate_chain.begin(),
470 aci_endorsements.certificate_chain.end());
477 catch (
const std::exception& e)
486 "SNP endorsements loaded from disk ({}) contained tcbm {}, "
487 "which does not match reported TCB of current attestation "
489 "Falling back to fetching fresh endorsements from server.",
491 aci_endorsements.tcbm,
495 catch (
const std::exception& e)
498 "Error attempting to use SNP endorsements from file: {}",
505 throw std::runtime_error(
506 "One or more SNP endorsements servers must be specified to fetch "
507 "the collateral for the attestation");
510 quote_endorsements_client = std::make_shared<QuoteEndorsementsClient>(
511 endpoint_config, [
this](std::vector<uint8_t>&& endorsements) {
512 std::lock_guard<pal::Mutex> guard(lock);
518 catch (
const std::exception& e)
523 quote_endorsements_client.reset();
526 quote_endorsements_client->fetch_endorsements();
532 throw std::runtime_error(fmt::format(
533 "Unsupported quote format: {}",
534 static_cast<int>(quote_info.
format)));
552 std::vector<uint8_t>&& startup_snapshot_)
554 std::lock_guard<pal::Mutex> guard(lock);
556 start_type = start_type_;
559 startup_snapshot = std::move(startup_snapshot_);
560 subject_alt_names = get_subject_alternative_names();
563 self_signed_node_cert = create_self_signed_cert(
570 accept_node_tls_connections();
585 network.
identity = std::make_unique<ccf::NetworkIdentity>(
596 history->set_service_signing_identity(
599 setup_consensus(
false, endorsed_node_cert);
605 return {self_signed_node_cert, network.
identity->cert};
610 return {self_signed_node_cert, {}};
616 throw std::logic_error(
617 "Recovery requires the certificate of the previous service "
624 network.
identity = std::make_unique<ccf::NetworkIdentity>(
631 return {self_signed_node_cert, network.
identity->cert};
635 throw std::logic_error(
636 fmt::format(
"Node was started in unknown mode {}", start_type));
649 auto network_ca = std::make_shared<::tls::CA>(std::string(
652 auto join_client_cert = std::make_unique<::tls::Cert>(
654 self_signed_node_cert,
655 node_sign_kp->private_key_pem(),
661 auto join_client = rpcsessions->create_client(
662 std::move(join_client_cert),
663 rpcsessions->get_app_protocol_main_interface());
665 auto [target_host, target_port] =
668 join_client->connect(
674 std::vector<uint8_t>&& data) {
675 std::lock_guard<pal::Mutex> guard(lock);
681 if (is_http_status_client_error(status))
683 auto error_msg = fmt::format(
684 "Join request to {} returned {} Bad Request: {}. Shutting "
685 "down node gracefully.",
688 std::string(data.begin(), data.end()));
691 AdminMessage::fatal_error_msg, to_host, error_msg);
693 else if (status != HTTP_STATUS_OK)
695 const auto& location = headers.find(http::headers::LOCATION);
698 (status == HTTP_STATUS_PERMANENT_REDIRECT ||
699 status == HTTP_STATUS_TEMPORARY_REDIRECT) &&
700 location != headers.end())
704 make_net_address(url.host, url.port);
705 LOG_INFO_FMT(
"Target node redirected to {}", location->second);
710 "An error occurred while joining the network: {} {}{}",
712 ccf::http_status_str(status),
715 fmt::format(
" '{}'", std::string(data.begin(), data.end())));
720 auto j = nlohmann::json::parse(data);
727 catch (
const std::exception& e)
730 "An error occurred while parsing the join network response");
732 "An error occurred while parsing the join network response: {}",
742 throw std::logic_error(
"Expected network info in join response");
745 network.
identity = std::make_unique<ccf::NetworkIdentity>(
747 seal_ledger_secret(*resp.
network_info->ledger_secrets.rbegin());
751 history->set_service_signing_identity(
757 if (!resp.
network_info->endorsed_certificate.has_value())
760 throw std::logic_error(
761 "Expected endorsed certificate in join response");
763 n2n_channels_cert = resp.
network_info->endorsed_certificate.value();
765 setup_consensus(resp.
network_info->public_only, n2n_channels_cert);
770 last_recovered_signed_idx =
772 setup_recovery_hook();
773 snapshotter->set_snapshot_generation(
false);
777 std::vector<ccf::kv::Version> view_history_ = {};
778 if (startup_snapshot_info)
783 deserialise_snapshot(
785 startup_snapshot_info->raw,
791 for (
auto& hook : hooks)
796 auto tx = network.
tables->create_read_only_tx();
798 auto sig = signatures->get();
799 if (!sig.has_value())
801 throw std::logic_error(
802 fmt::format(
"No signatures found after applying snapshot"));
811 startup_snapshot_info.reset();
815 "Joiner successfully resumed from snapshot at seqno {} and "
817 network.
tables->current_version(),
822 network.
tables->current_version(),
825 last_recovered_signed_idx);
827 snapshotter->set_last_snapshot_idx(
828 network.
tables->current_version());
829 history->start_signature_emit_timer();
842 if (join_periodic_task !=
nullptr)
844 join_periodic_task->cancel_task();
845 join_periodic_task =
nullptr;
849 "Node has now joined the network as node {}: {}",
851 (resp.
network_info->public_only ?
"public only" :
"all domains"));
856 "Node {} is waiting for votes of members to be trusted", self);
859 [
this](
const std::string& error_msg) {
860 std::lock_guard<pal::Mutex> guard(lock);
861 auto long_error_msg = fmt::format(
862 "Early error when joining existing network at {}: {}. Shutting "
863 "down node gracefully...",
868 AdminMessage::fatal_error_msg, to_host, long_error_msg);
885 const auto body = nlohmann::json(join_params).dump();
892 http::headers::CONTENT_TYPE, http::headervalues::contenttype::JSON);
895 join_client->send_request(std::move(r));
900 std::lock_guard<pal::Mutex> guard(lock);
909 std::lock_guard<pal::Mutex> guard(this->lock);
927 "JWT key auto-refresh: consensus not initialized, not starting "
931 jwt_key_auto_refresh = std::make_shared<JwtKeyAutoRefresh>(
938 self_signed_node_cert);
939 jwt_key_auto_refresh->start();
941 network.
tables->set_map_hook(
945 jwt_key_auto_refresh->schedule_once();
952 return jwt_key_auto_refresh->get_attempts();
962 throw std::logic_error(fmt::format(
963 "Node should be in state {} to start reading ledger",
970 last_recovered_idx + 1, last_recovered_idx + recovery_batch_size);
975 std::lock_guard<pal::Mutex> guard(lock);
979 const auto* data = entries.data();
980 auto size = entries.size();
984 recover_public_ledger_end_unsafe();
993 "Deserialising public ledger entry #{} [{} bytes]",
1002 auto r = network.tables->deserialize(entry,
true);
1003 result = r->apply();
1007 "Failed to deserialise public ledger entry: {}", result);
1008 recover_public_ledger_end_unsafe();
1011 ++last_recovered_idx;
1014 for (
auto& hook : r->get_hooks())
1019 catch (
const std::exception& e)
1022 "Failed to deserialise public ledger entry: {}", e.what());
1023 recover_public_ledger_end_unsafe();
1031 network.tables->compact(last_recovered_idx);
1032 auto tx = network.tables->create_read_only_tx();
1033 auto last_sig = tx.ro(network.signatures)->get();
1035 if (!last_sig.has_value())
1037 throw std::logic_error(
"Signature missing");
1041 "Read signature at {} for view {}",
1051 const auto view_start_idx =
1052 view_history.empty() ? 1 : last_recovered_signed_idx + 1;
1054 last_sig->view >= 0,
1055 "last_sig->view is invalid, {}",
1057 for (
auto i = view_history.size();
1058 i < static_cast<size_t>(last_sig->view);
1061 view_history.push_back(view_start_idx);
1063 last_recovered_signed_idx = last_recovered_idx;
1067 read_ledger_entries(
1068 last_recovered_idx + 1, last_recovered_idx + recovery_batch_size);
1073 std::lock_guard<pal::Mutex> guard(lock);
1075 history->start_signature_emit_timer();
1081 std::lock_guard<pal::Mutex> guard(lock);
1083 history->start_signature_emit_timer();
1084 auto_refresh_jwt_keys();
1096 const auto last_recovered_term = view_history.size();
1097 auto new_term = last_recovered_term + aft::starting_view_change;
1098 LOG_INFO_FMT(
"Setting term on public recovery store to {}", new_term);
1101 network.tables->rollback(
1102 {last_recovered_term, last_recovered_signed_idx}, new_term);
1103 ledger_truncate(last_recovered_signed_idx,
true);
1104 snapshotter->rollback(last_recovered_signed_idx);
1107 "End of public ledger recovery - Truncating ledger to last signed "
1109 last_recovered_term,
1110 last_recovered_signed_idx);
1112 auto tx = network.tables->create_read_only_tx();
1113 network.ledger_secrets->init(last_recovered_signed_idx + 1);
1116 snapshotter->init_after_public_recovery();
1117 snapshotter->set_snapshot_generation(
false);
1122 auto ls = tx.ro(network.signatures)->get();
1125 auto s = ls.value();
1131 throw std::logic_error(
"No signature found after recovery");
1135 auto lcs = tx.ro(network.cose_signatures)->get();
1136 if (lcs.has_value())
1143 cose::decode_ccf_receipt(cs,
false);
1144 auto issuer = receipt.phdr.cwt.iss;
1145 auto subject = receipt.phdr.cwt.sub;
1147 "COSE signature issuer: {}, subject: {}", issuer, subject);
1152 LOG_FAIL_FMT(
"COSE signature decode error: {}", e.what());
1158 LOG_INFO_FMT(
"No COSE signature found after recovery");
1161 history->set_service_signing_identity(
1162 network.identity->get_key_pair(), cs_cfg);
1170 setup_consensus(
true);
1171 auto_refresh_jwt_keys();
1175 consensus->force_become_primary(index,
view, view_history, index);
1177 create_and_send_boot_request(
1186 std::lock_guard<pal::Mutex> guard(lock);
1190 "Node in state {} cannot recover private ledger entries", sm.value());
1194 const auto* data = entries.data();
1195 auto size = entries.size();
1199 recover_private_ledger_end_unsafe();
1208 "Deserialising private ledger entry {} [{}]",
1209 last_recovered_idx + 1,
1216 result = recovery_store->deserialize(entry)->apply();
1220 "Failed to deserialise private ledger entry: {}", result);
1223 recovery_store->rollback({0, last_recovered_idx}, 0);
1224 recover_private_ledger_end_unsafe();
1227 ++last_recovered_idx;
1229 catch (
const std::exception& e)
1232 "Failed to deserialise private ledger entry: {}", e.what());
1233 recover_private_ledger_end_unsafe();
1239 recovery_store->compact(last_recovered_idx);
1243 if (recovery_store->current_version() == recovery_v)
1245 LOG_INFO_FMT(
"Reached recovery final version at {}", recovery_v);
1246 recover_private_ledger_end_unsafe();
1250 read_ledger_entries(
1251 last_recovered_idx + 1,
1252 std::min(last_recovered_idx + recovery_batch_size, recovery_v));
1264 "Try end private recovery at {}. Is primary: {}",
1268 if (recovery_v != recovery_store->current_version())
1270 throw std::logic_error(fmt::format(
1271 "Private recovery did not reach public ledger seqno: {}/{}",
1272 recovery_store->current_version(),
1278 if (h->get_replicated_state_root() != recovery_root)
1280 throw std::logic_error(fmt::format(
1281 "Root of public store does not match root of private store at {}",
1285 network.tables->swap_private_maps(*recovery_store);
1286 recovery_store.reset();
1292 snapshotter->set_snapshot_generation(
true);
1298 "Try end private recovery at {}. Trigger service opening",
1301 auto tx = network.tables->create_tx();
1307 auto active_service = service->get();
1309 if (!active_service.has_value())
1311 throw std::logic_error(fmt::format(
1312 "Error in {}: no value in {}", __func__, Tables::SERVICE));
1316 active_service->status !=
1319 throw std::logic_error(fmt::format(
1320 "Error in {}: current service status is {}",
1322 active_service->status));
1332 share_manager.issue_recovery_shares(tx);
1337 tx, *network.identity->get_key_pair()))
1339 throw std::logic_error(
"Service could not be opened");
1345 trigger_snapshot(tx);
1349 throw std::logic_error(
1350 "Could not commit transaction when finishing network recovery");
1353 recovered_encrypted_ledger_secrets.clear();
1365 network.tables->set_map_hook(
1366 network.encrypted_ledger_secrets.get_name(),
1374 throw std::logic_error(fmt::format(
1375 "Unexpected removal from {} table",
1376 network.encrypted_ledger_secrets.get_name()));
1379 network.ledger_secrets->adjust_previous_secret_stored_version(
1382 network.tables->unset_map_hook(
1383 network.encrypted_ledger_secrets.get_name());
1394 std::lock_guard<pal::Mutex> guard(lock);
1396 if (is_reading_public_ledger())
1398 recover_public_ledger_end_unsafe();
1400 else if (is_reading_private_ledger())
1402 recover_private_ledger_end_unsafe();
1407 "Node in state {} cannot finalise ledger recovery", sm.value());
1417 recovery_store = std::make_shared<ccf::kv::Store>(
1420 auto recovery_history = std::make_shared<MerkleTxHistory>(
1428 auto recovery_encryptor = make_encryptor();
1430 recovery_store->set_history(recovery_history);
1431 recovery_store->set_encryptor(recovery_encryptor);
1434 recovery_v = network.tables->current_version();
1438 if (startup_snapshot_info)
1440 std::vector<ccf::kv::Version> view_history_;
1442 deserialise_snapshot(
1444 startup_snapshot_info->raw,
1448 config.recover.previous_service_identity);
1449 startup_snapshot_info.reset();
1453 "Recovery store successfully setup at {}. Target recovery seqno: {}",
1454 recovery_store->current_version(),
1460 share_manager.shuffle_recovery_shares(tx);
1468 throw std::logic_error(
"Could not cast tx to CommittableTx");
1477 if (committable_tx ==
nullptr)
1479 throw std::logic_error(
"Could not cast tx to CommittableTx");
1481 committable_tx->set_tx_flag(
1489 std::lock_guard<pal::Mutex> guard(lock);
1491 auto* service = tx.
rw<
Service>(Tables::SERVICE);
1492 auto service_info = service->get();
1493 if (!service_info.has_value())
1495 throw std::logic_error(
1496 "Service information cannot be found to transition service to "
1503 service_info->status == ServiceStatus::WAITING_FOR_RECOVERY_SHARES ||
1504 service_info->status == ServiceStatus::OPEN)
1507 "Service in state {} is already open", service_info->status);
1511 if (service_info->status == ServiceStatus::RECOVERING)
1513 const auto prev_ident =
1516 if (!prev_ident.has_value() || !identities.
previous.has_value())
1518 throw std::logic_error(
1519 "Recovery with service certificates requires both, a previous "
1520 "service identity written to the KV during recovery genesis and a "
1521 "transition_service_to_open proposal that contains previous and "
1522 "next service certificates");
1527 if (prev_ident.value() != from_proposal)
1529 throw std::logic_error(fmt::format(
1530 "Previous service identity does not match.\nActual:\n{}\nIn "
1533 from_proposal.
str()));
1537 if (identities.
next != service_info->cert)
1539 throw std::logic_error(fmt::format(
1540 "Service identity mismatch: the next service identity in the "
1541 "transition_service_to_open proposal does not match the current "
1542 "service identity:\nNext:\n{}\nCurrent:\n{}",
1544 service_info->cert.str()));
1547 if (is_part_of_public_network())
1551 ShareManager::clear_submitted_recovery_shares(tx);
1552 service_info->status = ServiceStatus::WAITING_FOR_RECOVERY_SHARES;
1553 service->put(service_info.value());
1554 if (config.recover.previous_sealed_ledger_secret_location.has_value())
1557 ->put(RecoveryType::LOCAL_UNSEALING);
1558 auto unsealed_ls = unseal_ledger_secret();
1559 LOG_INFO_FMT(
"Unsealed ledger secret, initiating private recovery");
1560 initiate_private_recovery_unsafe(tx, unsealed_ls);
1565 ->put(RecoveryType::RECOVERY_SHARES);
1570 if (is_part_of_network())
1577 share_manager.issue_recovery_shares(tx);
1579 catch (
const std::logic_error& e)
1581 throw std::logic_error(
1582 fmt::format(
"Failed to issue recovery shares: {}", e.what()));
1585 InternalTablesAccess::open_service(tx);
1586 InternalTablesAccess::endorse_previous_identity(
1587 tx, *network.identity->get_key_pair());
1588 trigger_snapshot(tx);
1592 throw std::logic_error(
1593 fmt::format(
"Node in state {} cannot open service", sm.value()));
1601 const std::optional<LedgerSecretPtr>& unsealed_ledger_secret =
1604 sm.expect(NodeStartupState::partOfPublicNetwork);
1606 share_manager.restore_recovery_shares_info(
1607 tx, recovered_encrypted_ledger_secrets, unsealed_ledger_secret);
1611 LedgerSecretsBroadcast::broadcast_some(
1612 InternalTablesAccess::get_trusted_nodes(tx),
1613 tx.
wo(network.secrets),
1614 recovered_ledger_secrets);
1619 const std::optional<LedgerSecretPtr>& unsealed_ledger_secret =
1620 std::nullopt)
override
1622 std::lock_guard<pal::Mutex> guard(lock);
1623 initiate_private_recovery_unsafe(tx, unsealed_ledger_secret);
1629 void tick(std::chrono::milliseconds elapsed)
1632 !sm.check(NodeStartupState::partOfNetwork) &&
1633 !sm.check(NodeStartupState::partOfPublicNetwork) &&
1634 !sm.check(NodeStartupState::readingPrivateLedger))
1641 if (sm.check(NodeStartupState::partOfNetwork))
1643 const auto tx_id =
consensus->get_committed_txid();
1644 indexer->update_strategies(elapsed, {tx_id.first, tx_id.second});
1647 n2n_channels->tick(elapsed);
1653 !sm.check(NodeStartupState::partOfNetwork) &&
1654 !sm.check(NodeStartupState::partOfPublicNetwork) &&
1655 !sm.check(NodeStartupState::readingPrivateLedger))
1666 stop_noticed =
true;
1671 return stop_noticed;
1676 auto [msg_type, from, payload] =
1677 ringbuffer::read_message<node_inbound>(data, size);
1679 const auto* payload_data = payload.data;
1680 auto payload_size = payload.size;
1682 if (msg_type == NodeMsgType::forwarded_msg)
1684 cmd_forwarder->recv_message(from, payload_data, payload_size);
1690 !sm.check(NodeStartupState::partOfNetwork) &&
1691 !sm.check(NodeStartupState::partOfPublicNetwork) &&
1692 !sm.check(NodeStartupState::readingPrivateLedger))
1695 "Ignoring node msg received too early - current state is {}",
1704 n2n_channels->recv_channel_message(
1705 from, payload_data, payload_size);
1711 consensus->recv_message(from, payload_data, payload_size);
1717 LOG_FAIL_FMT(
"Unknown node message type: {}", msg_type);
1730 (sm.check(NodeStartupState::partOfNetwork) ||
1731 sm.check(NodeStartupState::partOfPublicNetwork) ||
1732 sm.check(NodeStartupState::readingPrivateLedger)) &&
1739 (sm.check(NodeStartupState::partOfNetwork) ||
1740 sm.check(NodeStartupState::partOfPublicNetwork) ||
1741 sm.check(NodeStartupState::readingPrivateLedger)) &&
1752 return sm.check(NodeStartupState::initialized);
1757 return sm.check(NodeStartupState::partOfNetwork);
1762 return sm.check(NodeStartupState::readingPublicLedger);
1767 return sm.check(NodeStartupState::readingPrivateLedger);
1772 return sm.check(NodeStartupState::partOfPublicNetwork);
1777 const auto val = sm.value();
1778 return val == NodeStartupState::partOfNetwork ||
1779 val == NodeStartupState::partOfPublicNetwork ||
1780 val == NodeStartupState::readingPrivateLedger;
1785 std::lock_guard<pal::Mutex> guard(lock);
1786 auto s = sm.value();
1787 if (s == NodeStartupState::readingPrivateLedger)
1789 return {s, recovery_v, recovery_store->current_version()};
1792 return {s, std::nullopt, std::nullopt};
1797 std::lock_guard<pal::Mutex> guard(lock);
1798 sm.expect(NodeStartupState::partOfNetwork);
1807 const auto service_status = InternalTablesAccess::get_service_status(tx);
1809 !service_status.has_value() ||
1810 service_status.value() != ServiceStatus::OPEN)
1812 LOG_FAIL_FMT(
"Cannot rekey ledger while the service is not open");
1820 share_manager.issue_recovery_shares(tx, new_ledger_secret);
1821 LedgerSecretsBroadcast::broadcast_new(
1822 InternalTablesAccess::get_trusted_nodes(tx),
1823 tx.
wo(network.secrets),
1824 std::move(new_ledger_secret));
1836 std::lock_guard<pal::Mutex> guard(lock);
1837 return startup_seqno;
1842 return rpcsessions->get_session_metrics();
1847 std::lock_guard<pal::Mutex> guard(lock);
1848 return self_signed_node_cert;
1853 if (history ==
nullptr)
1855 throw std::logic_error(
1856 "Attempting to access COSE signatures config before history has been "
1860 return history->get_cose_signatures_config();
1864 bool is_ip(
const std::string_view& hostname)
1872 const auto final_component =
1873 ccf::nonstd::split(ccf::nonstd::split(hostname,
".").back(),
":")
1875 if (final_component.empty())
1877 throw std::runtime_error(fmt::format(
1878 "{} has a trailing period, is not a valid hostname", hostname));
1881 return std::ranges::all_of(
1882 final_component, [](
char c) {
return c >=
'0' && c <=
'9'; });
1885 std::vector<ccf::crypto::SubjectAltName> get_subject_alternative_names()
1890 if (!config.node_certificate.subject_alt_names.empty())
1892 return ccf::crypto::sans_from_string_list(
1893 config.node_certificate.subject_alt_names);
1898 std::vector<ccf::crypto::SubjectAltName> sans;
1899 for (
const auto& [_, interface] : config.network.rpc_interfaces)
1901 auto host = split_net_address(interface.published_address).first;
1902 sans.push_back({
host, is_ip(
host)});
1907 void accept_node_tls_connections()
1911 rpcsessions->set_node_cert(
1912 self_signed_node_cert, node_sign_kp->private_key_pem());
1916 void accept_network_tls_connections()
1921 endorsed_node_cert.has_value(),
1922 "Node certificate should be endorsed before accepting endorsed "
1925 if (
auto cert_opt = endorsed_node_cert; cert_opt.has_value())
1927 const auto& endorsed_cert = cert_opt.value();
1928 rpcsessions->set_network_cert(
1929 endorsed_cert, node_sign_kp->private_key_pem());
1934 auto find_frontend(ActorsType actor)
1936 auto fe = rpc_map->find(actor);
1937 if (!fe.has_value())
1939 throw std::logic_error(
1940 fmt::format(
"Cannot find {} frontend", (
int)actor));
1945 void open_frontend(ActorsType actor)
1947 find_frontend(actor)->open();
1950 void open_user_frontend()
1952 open_frontend(ActorsType::users);
1955 bool is_member_frontend_open_unsafe()
1957 return find_frontend(ActorsType::members)->is_open();
1960 bool is_member_frontend_open()
override
1962 std::lock_guard<pal::Mutex> guard(lock);
1963 return is_member_frontend_open_unsafe();
1966 bool is_user_frontend_open()
override
1968 std::lock_guard<pal::Mutex> guard(lock);
1969 return find_frontend(ActorsType::users)->is_open();
1972 std::vector<uint8_t> serialize_create_request(
1973 View create_view,
bool create_consortium =
true)
1975 CreateNetworkNodeToNode::In create_params;
1979 if (create_consortium)
1981 create_params.genesis_info = config.start;
1984 create_params.node_id = self;
1985 create_params.certificate_signing_request = node_sign_kp->create_csr(
1986 config.node_certificate.subject_name, subject_alt_names);
1987 create_params.node_endorsed_certificate =
1988 ccf::crypto::create_endorsed_cert(
1989 create_params.certificate_signing_request,
1990 config.startup_host_time,
1991 config.node_certificate.initial_validity_days,
1992 network.identity->priv_key,
1993 network.identity->cert);
1997 history->set_endorsed_certificate(
1998 create_params.node_endorsed_certificate);
2000 create_params.public_key = node_sign_kp->public_key_pem();
2001 create_params.service_cert = network.identity->cert;
2002 create_params.quote_info = quote_info;
2003 create_params.public_encryption_key = node_encrypt_kp->public_key_pem();
2004 create_params.measurement = node_measurement;
2005 create_params.snp_uvm_endorsements = snp_uvm_endorsements;
2006 create_params.snp_security_policy =
2007 config.attestation.environment.security_policy;
2009 create_params.node_info_network = config.network;
2010 create_params.node_data = config.node_data;
2011 create_params.service_data = config.service_data;
2012 create_params.create_txid = {create_view, last_recovered_signed_idx + 1};
2014 const auto body = nlohmann::json(create_params).dump();
2019 ccf::http::headers::CONTENT_TYPE,
2020 ccf::http::headervalues::contenttype::JSON);
2022 request.set_body(body);
2024 return request.build_request();
2027 bool extract_create_result(
const std::shared_ptr<RpcContext>& ctx)
2035 const auto status = ctx->get_response_status();
2036 const auto& raw_body = ctx->get_response_body();
2037 if (status != HTTP_STATUS_OK)
2040 "Create response is error: {} {}\n{}",
2043 std::string(raw_body.begin(), raw_body.end()));
2047 const auto body = nlohmann::json::parse(raw_body);
2048 if (!body.is_boolean())
2050 LOG_FAIL_FMT(
"Expected boolean body in create response");
2052 "Expected boolean body in create response: {}", body.dump());
2059 bool send_create_request(
const std::vector<uint8_t>& packed)
2061 auto node_session = std::make_shared<SessionContext>(
2062 InvalidSessionId, self_signed_node_cert.raw());
2065 std::shared_ptr<ccf::RpcHandler> search =
2066 ::http::fetch_rpc_handler(ctx, this->rpc_map);
2068 search->process(ctx);
2070 return extract_create_result(ctx);
2073 void create_and_send_boot_request(
2074 View create_view,
bool create_consortium =
true)
2080 if (!this->send_create_request(
2081 this->serialize_create_request(create_view, create_consortium)))
2083 throw std::runtime_error(
2084 "Service creation request could not be committed");
2086 if (create_consortium)
2088 this->advance_part_of_network();
2092 this->advance_part_of_public_network();
2097 void begin_private_recovery()
2099 sm.expect(NodeStartupState::partOfPublicNetwork);
2103 setup_private_recovery_store();
2105 reset_recovery_hook();
2106 setup_one_off_secret_hook();
2109 sm.advance(NodeStartupState::readingPrivateLedger);
2110 last_recovered_idx = recovery_store->current_version();
2111 read_ledger_entries(
2112 last_recovered_idx + 1, last_recovered_idx + recovery_batch_size);
2115 void setup_basic_hooks()
2117 network.tables->set_map_hook(
2118 network.secrets.get_name(),
2123 if (!is_part_of_network())
2129 const auto& ledger_secrets_for_nodes = w;
2130 if (!ledger_secrets_for_nodes.has_value())
2132 throw std::logic_error(fmt::format(
2133 "Unexpected removal from {} table",
2134 network.secrets.get_name()));
2137 for (
const auto& [node_id, encrypted_ledger_secrets] :
2138 ledger_secrets_for_nodes.value())
2140 if (node_id != self)
2146 for (
const auto& encrypted_ledger_secret :
2147 encrypted_ledger_secrets)
2149 auto plain_ledger_secret = LedgerSecretsBroadcast::decrypt(
2150 node_encrypt_kp, encrypted_ledger_secret.encrypted_secret);
2155 auto ledger_secret = std::make_shared<LedgerSecret>(
2156 std::move(plain_ledger_secret), hook_version);
2157 seal_ledger_secret(hook_version + 1, ledger_secret);
2158 network.ledger_secrets->set_secret(
2159 hook_version + 1, std::move(ledger_secret));
2166 network.tables->set_global_hook(
2167 network.secrets.get_name(),
2172 if (!is_part_of_public_network())
2177 const auto& ledger_secrets_for_nodes = w;
2178 if (!ledger_secrets_for_nodes.has_value())
2180 throw std::logic_error(fmt::format(
2181 "Unexpected removal from {} table", network.secrets.get_name()));
2184 for (
const auto& [node_id, encrypted_ledger_secrets] :
2185 ledger_secrets_for_nodes.value())
2187 if (node_id != self)
2194 for (
const auto& encrypted_ledger_secret : encrypted_ledger_secrets)
2199 if (!encrypted_ledger_secret.version.has_value())
2201 throw std::logic_error(fmt::format(
2202 "Commit hook at seqno {} for table {}: no version for "
2203 "encrypted ledger secret",
2205 network.secrets.get_name()));
2208 auto plain_ledger_secret = LedgerSecretsBroadcast::decrypt(
2209 node_encrypt_kp, encrypted_ledger_secret.encrypted_secret);
2211 restored_ledger_secrets.emplace(
2212 encrypted_ledger_secret.version.value(),
2213 std::make_shared<LedgerSecret>(
2214 std::move(plain_ledger_secret),
2215 encrypted_ledger_secret.previous_secret_stored_version));
2218 if (!restored_ledger_secrets.empty())
2222 network.ledger_secrets->restore_historical(
2223 std::move(restored_ledger_secrets));
2224 begin_private_recovery();
2230 "Found no ledger secrets for this node ({}) in global commit hook "
2233 network.secrets.get_name(),
2237 network.tables->set_global_hook(
2238 network.nodes.get_name(),
2241 std::vector<NodeId> retired_committed_nodes;
2242 for (
const auto& [node_id, node_info] : w)
2244 if (node_info.has_value() && node_info->retired_committed)
2246 retired_committed_nodes.push_back(node_id);
2250 hook_version, retired_committed_nodes);
2259 network.tables->set_map_hook(
2260 network.node_endorsed_certificates.get_name(),
2267 "[local] node_endorsed_certificates local hook at version {}, "
2271 for (
auto const& [node_id, endorsed_certificate] : w)
2273 if (node_id != self)
2276 "[local] Ignoring endorsed certificate for other node {}",
2281 if (!endorsed_certificate.has_value())
2284 "[local] Endorsed cert for self ({}) has been deleted", self);
2285 throw std::logic_error(fmt::format(
2286 "Could not find endorsed node certificate for {}", self));
2289 std::lock_guard<pal::Mutex> guard(lock);
2291 if (endorsed_node_cert.has_value())
2294 "[local] Previous endorsed node cert was:\n{}",
2295 endorsed_node_cert->str());
2298 endorsed_node_cert = endorsed_certificate.value();
2300 "[local] Under lock, setting endorsed node cert to:\n{}",
2301 endorsed_node_cert->str());
2302 history->set_endorsed_certificate(endorsed_node_cert.value());
2303 n2n_channels->set_endorsed_node_cert(endorsed_node_cert.value());
2309 network.tables->set_global_hook(
2310 network.node_endorsed_certificates.get_name(),
2316 "[global] node_endorsed_certificates global hook at version {}, "
2320 for (
auto const& [node_id, endorsed_certificate] : w)
2322 if (node_id != self)
2325 "[global] Ignoring endorsed certificate for other node {}",
2330 if (!endorsed_certificate.has_value())
2333 "[global] Endorsed cert for self ({}) has been deleted",
2335 throw std::logic_error(fmt::format(
2336 "Could not find endorsed node certificate for {}", self));
2339 std::lock_guard<pal::Mutex> guard(lock);
2341 LOG_INFO_FMT(
"[global] Accepting network connections");
2342 accept_network_tls_connections();
2344 if (is_member_frontend_open_unsafe())
2352 auto [valid_from, valid_to] =
2354 ->validity_period();
2356 "[global] Member frontend is open, so refreshing self-signed "
2359 "[global] Previously:\n{}", self_signed_node_cert.str());
2360 self_signed_node_cert = create_self_signed_cert(
2362 config.node_certificate.subject_name,
2366 LOG_INFO_FMT(
"[global] Now:\n{}", self_signed_node_cert.str());
2369 accept_node_tls_connections();
2375 "[global] Self-signed node cert remains:\n{}",
2376 self_signed_node_cert.str());
2380 open_frontend(ActorsType::members);
2384 network.tables->set_global_hook(
2385 network.service.get_name(),
2390 throw std::logic_error(
"Unexpected deletion in service value");
2396 auto current_pubk_pem =
2399 if (hook_pubk_pem != current_pubk_pem)
2402 "Ignoring historical service open at seqno {} for {}",
2409 "Executing global hook for service table at {}, to service "
2410 "status {}. Cert is:\n{}",
2415 network.identity->set_certificate(w->cert);
2416 if (w->status == ServiceStatus::OPEN)
2418 open_user_frontend();
2421 LOG_INFO_FMT(
"Service open at seqno {}", hook_version);
2433 std::lock_guard<pal::Mutex> guard(lock);
2434 return last_recovered_signed_idx;
2437 void setup_recovery_hook()
2439 network.tables->set_map_hook(
2440 network.encrypted_ledger_secrets.get_name(),
2446 auto encrypted_ledger_secret_info = w;
2447 if (!encrypted_ledger_secret_info.has_value())
2449 throw std::logic_error(fmt::format(
2450 "Unexpected removal from {} table",
2451 network.encrypted_ledger_secrets.get_name()));
2456 if (!encrypted_ledger_secret_info->next_version.has_value())
2458 encrypted_ledger_secret_info->next_version = version + 1;
2461 if (encrypted_ledger_secret_info->previous_ledger_secret
2465 "Recovering encrypted ledger secret valid at seqno {}",
2466 encrypted_ledger_secret_info->previous_ledger_secret->version);
2469 recovered_encrypted_ledger_secrets.emplace_back(
2470 std::move(encrypted_ledger_secret_info.value()));
2476 void reset_recovery_hook()
2478 network.tables->unset_map_hook(
2479 network.encrypted_ledger_secrets.get_name());
2482 void setup_n2n_channels(
2483 const std::optional<ccf::crypto::Pem>& endorsed_node_certificate_ =
2490 n2n_channels->initialize(
2491 self, network.identity->cert, node_sign_kp, endorsed_node_certificate_);
2494 void setup_cmd_forwarder()
2496 cmd_forwarder->initialize(self);
2499 void setup_history()
2503 throw std::logic_error(
"History already initialised");
2506 history = std::make_shared<MerkleTxHistory>(
2513 network.tables->set_history(history);
2516 void setup_encryptor()
2520 throw std::logic_error(
"Encryptor already initialised");
2523 encryptor = make_encryptor();
2524 network.tables->set_encryptor(encryptor);
2527 void setup_consensus(
2528 bool public_only =
false,
2529 const std::optional<ccf::crypto::Pem>& endorsed_node_certificate_ =
2532 setup_n2n_channels(endorsed_node_certificate_);
2533 setup_cmd_forwarder();
2535 auto shared_state = std::make_shared<aft::State>(self);
2537 auto node_client = std::make_shared<HTTPNodeClient>(
2538 rpc_map, node_sign_kp, self_signed_node_cert, endorsed_node_cert);
2543 std::make_unique<::consensus::LedgerEnclave>(writer_factory),
2549 network.tables->set_consensus(
consensus);
2550 network.tables->set_snapshotter(snapshotter);
2554 network.tables->set_map_hook(
2555 network.nodes.get_name(),
2559 return std::make_unique<ConfigurationChangeHook>(version, w);
2568 network.tables->set_map_hook(
2569 network.signatures.get_name(),
2571 [s = this->snapshotter](
2574 assert(w.has_value());
2575 auto sig = w.value();
2576 s->record_signature(version, sig.sig, sig.node, sig.cert);
2580 network.tables->set_map_hook(
2581 network.serialise_tree.get_name(),
2583 [s = this->snapshotter](
2586 assert(w.has_value());
2587 const auto& tree = w.value();
2588 s->record_serialised_tree(version, tree);
2592 network.tables->set_map_hook(
2593 network.snapshot_evidence.get_name(),
2595 [s = this->snapshotter](
2598 assert(w.has_value());
2599 auto snapshot_evidence = w.value();
2600 s->record_snapshot_evidence_idx(version, snapshot_evidence);
2604 setup_basic_hooks();
2607 void setup_snapshotter()
2611 throw std::logic_error(
"Snapshotter already initialised");
2613 snapshotter = std::make_shared<Snapshotter>(
2614 writer_factory, network.tables, config.snapshots.tx_count);
2620 ::consensus::ledger_get_range,
2630 ::consensus::ledger_truncate, to_host, idx, recovery_mode);
2633 void seal_ledger_secret(
const VersionedLedgerSecret& ledger_secret)
2635 seal_ledger_secret(ledger_secret.first, ledger_secret.second);
2638 void seal_ledger_secret(
2639 const kv::Version& version,
const LedgerSecretPtr& ledger_secret)
2641 if (!config.sealed_ledger_secret_location.has_value())
2647 snp_tcb_version.has_value(),
"TCB version must be set before sealing");
2649 if (
auto loc_opt = config.sealed_ledger_secret_location;
2650 loc_opt.has_value())
2652 if (
auto tcb_opt = snp_tcb_version; tcb_opt.has_value())
2654 const auto& sealed_location = loc_opt.value();
2655 const auto& tcb_version = tcb_opt.value();
2657 sealed_location, tcb_version, version, ledger_secret);
2665 snp_tcb_version.has_value(),
2666 "TCB version must be set when unsealing ledger secret");
2669 config.recover.previous_sealed_ledger_secret_location.has_value(),
2670 "Previous sealed ledger secret location must be set");
2672 if (
auto path_opt = config.recover.previous_sealed_ledger_secret_location;
2673 path_opt.has_value())
2675 const auto& ledger_secret_path = path_opt.value();
2676 auto max_version = network.tables->current_version();
2678 ledger_secret_path, max_version);
2687 n2n_channels->set_message_limit(message_limit);
2692 n2n_channels->set_idle_timeout(idle_timeout);
2702 return network.identity->cert;
2707 const ::http::URL& url,
2712 const std::vector<std::string>& ca_certs = {},
2713 const std::string& app_protocol =
"HTTP1",
2714 bool authenticate_as_node_client_certificate =
false)
override
2716 std::optional<ccf::crypto::Pem> client_cert = std::nullopt;
2717 std::optional<ccf::crypto::Pem> client_cert_key = std::nullopt;
2718 if (authenticate_as_node_client_certificate)
2721 endorsed_node_cert ? *endorsed_node_cert : self_signed_node_cert;
2722 client_cert_key = node_sign_kp->private_key_pem();
2725 auto ca = std::make_shared<::tls::CA>(ca_certs,
true);
2726 std::shared_ptr<::tls::Cert> ca_cert =
2727 std::make_shared<::tls::Cert>(ca, client_cert, client_cert_key);
2728 auto client = rpcsessions->create_client(ca_cert, app_protocol);
2734 http::HeaderMap&& headers,
2735 std::vector<uint8_t>&& data) {
2736 return callback(status, std::move(headers), std::move(data));
2738 client->send_request(std::move(req));
2743 snapshotter->write_snapshot(snapshot_buf, request_id);
2748 return network.tables;
2753 return writer_factory;
#define CCF_ASSERT_FMT(expr,...)
Definition ccf_assert.h:10
#define CCF_ASSERT(expr, msg)
Definition ccf_assert.h:14
Definition raft_types.h:41
Definition node_interface.h:22
static std::optional< pal::snp::Attestation > get_snp_attestation(const QuoteInfo "e_info)
Definition quote.cpp:146
static std::optional< HostData > get_host_data(const QuoteInfo "e_info)
Definition quote.cpp:169
static QuoteVerificationResult verify_quote_against_store(ccf::kv::ReadOnlyTx &tx, const QuoteInfo "e_info, const std::vector< uint8_t > &expected_node_public_key_der, pal::PlatformAttestationMeasurement &measurement)
Definition quote.cpp:311
static std::optional< pal::PlatformAttestationMeasurement > get_measurement(const QuoteInfo "e_info)
Definition quote.cpp:129
void set_node_id(const NodeId &id_)
Definition history.h:676
ccf::crypto::Sha256Hash get_replicated_state_root() override
Definition history.h:716
static bool open_service(ccf::kv::Tx &tx)
Definition internal_tables_access.h:683
static bool endorse_previous_identity(ccf::kv::Tx &tx, const ccf::crypto::ECKeyPair_OpenSSL &service_key)
Definition internal_tables_access.h:540
Definition node_state.h:87
void write_snapshot(std::span< uint8_t > snapshot_buf, size_t request_id)
Definition node_state.h:2741
void start_ledger_recovery_unsafe()
Definition node_state.h:958
bool rekey_ledger(ccf::kv::Tx &tx) override
Definition node_state.h:1795
bool is_part_of_public_network() const override
Definition node_state.h:1770
NodeState(ringbuffer::AbstractWriterFactory &writer_factory, NetworkState &network, std::shared_ptr< RPCSessions > rpcsessions, ccf::crypto::CurveID curve_id_)
Definition node_state.h:214
void setup_one_off_secret_hook()
Definition node_state.h:1359
void tick_end()
Definition node_state.h:1650
void recover_private_ledger_entries(const std::vector< uint8_t > &entries)
Definition node_state.h:1184
void recv_node_inbound(const uint8_t *data, size_t size)
Definition node_state.h:1674
ccf::crypto::Pem get_network_cert() override
Definition node_state.h:2700
bool is_reading_private_ledger() const override
Definition node_state.h:1765
std::optional< ccf::NodeId > get_primary() override
Definition node_state.h:1745
void trigger_ledger_chunk(ccf::kv::Tx &tx) override
Definition node_state.h:1463
bool is_primary() const override
Definition node_state.h:1727
void recover_public_ledger_end_unsafe()
Definition node_state.h:1090
SessionMetrics get_session_metrics() override
Definition node_state.h:1840
std::shared_ptr< ccf::kv::Store > get_store() override
Definition node_state.h:2746
void initiate_join()
Definition node_state.h:898
void advance_part_of_network()
Definition node_state.h:1079
void advance_part_of_public_network()
Definition node_state.h:1071
ccf::kv::Version get_startup_snapshot_seqno() override
Definition node_state.h:1834
const ccf::COSESignaturesConfig & get_cose_signatures_config() override
Definition node_state.h:1851
ringbuffer::AbstractWriterFactory & get_writer_factory() override
Definition node_state.h:2751
void auto_refresh_jwt_keys()
Definition node_state.h:922
void recover_ledger_end()
Definition node_state.h:1392
void initiate_private_recovery(ccf::kv::Tx &tx, const std::optional< LedgerSecretPtr > &unsealed_ledger_secret=std::nullopt) override
Definition node_state.h:1617
void initiate_join_unsafe()
Definition node_state.h:645
void stop_notice() override
Definition node_state.h:1663
void set_n2n_message_limit(size_t message_limit)
Definition node_state.h:2685
void make_http_request(const ::http::URL &url, ::http::Request &&req, std::function< bool(ccf::http_status status, http::HeaderMap &&, std::vector< uint8_t > &&)> callback, const std::vector< std::string > &ca_certs={}, const std::string &app_protocol="HTTP1", bool authenticate_as_node_client_certificate=false) override
Definition node_state.h:2706
bool can_replicate() override
Definition node_state.h:1736
void transition_service_to_open(ccf::kv::Tx &tx, AbstractGovernanceEffects::ServiceIdentities identities) override
Definition node_state.h:1485
QuoteVerificationResult verify_quote(ccf::kv::ReadOnlyTx &tx, const QuoteInfo "e_info_, const std::vector< uint8_t > &expected_node_public_key_der, pal::PlatformAttestationMeasurement &measurement) override
Definition node_state.h:231
bool is_reading_public_ledger() const override
Definition node_state.h:1760
void launch_node()
Definition node_state.h:278
void initiate_quote_generation()
Definition node_state.h:408
void initialize(const ccf::consensus::Configuration &consensus_config_, std::shared_ptr< RPCMap > rpc_map_, std::shared_ptr< AbstractRPCResponder > rpc_sessions_, std::shared_ptr< indexing::Indexer > indexer_, size_t sig_tx_interval_, size_t sig_ms_interval_)
Definition node_state.h:244
void setup_private_recovery_store()
Definition node_state.h:1415
const ccf::StartupConfig & get_node_config() const override
Definition node_state.h:2695
void trigger_snapshot(ccf::kv::Tx &tx) override
Definition node_state.h:1474
bool is_in_initialised_state() const override
Definition node_state.h:1750
bool has_received_stop_notice() override
Definition node_state.h:1669
bool is_part_of_network() const override
Definition node_state.h:1755
void start_join_timer()
Definition node_state.h:904
ExtendedState state() override
Definition node_state.h:1783
void trigger_recovery_shares_refresh(ccf::kv::Tx &tx) override
Definition node_state.h:1458
void set_n2n_idle_timeout(std::chrono::milliseconds idle_timeout)
Definition node_state.h:2690
NodeId get_node_id() const
Definition node_state.h:1829
void tick(std::chrono::milliseconds elapsed)
Definition node_state.h:1629
NodeCreateInfo create(StartType start_type_, const ccf::StartupConfig &config_, std::vector< uint8_t > &&startup_snapshot_)
Definition node_state.h:549
void recover_public_ledger_entries(const std::vector< uint8_t > &entries)
Definition node_state.h:973
void recover_private_ledger_end_unsafe()
Definition node_state.h:1256
void initiate_private_recovery_unsafe(ccf::kv::Tx &tx, const std::optional< LedgerSecretPtr > &unsealed_ledger_secret=std::nullopt)
Definition node_state.h:1599
ccf::crypto::Pem get_self_signed_certificate() override
Definition node_state.h:1845
size_t get_jwt_attempts() override
Definition node_state.h:950
bool is_accessible_to_members() const override
Definition node_state.h:1775
Definition share_manager.h:168
static void clear_submitted_recovery_shares(ccf::kv::Tx &tx)
Definition share_manager.h:651
Definition ec_key_pair.h:16
const std::string & str() const
Definition pem.h:46
Definition sha256_hash.h:16
Definition committable_tx.h:19
@ LEDGER_CHUNK_AT_NEXT_SIGNATURE
@ SNAPSHOT_AT_NEXT_SIGNATURE
M::ReadOnlyHandle * ro(M &m)
Definition tx.h:168
M::Handle * rw(M &m)
Definition tx.h:211
M::WriteOnlyHandle * wo(M &m)
Definition tx.h:232
std::map< K, std::optional< V > > Write
Definition map.h:40
static ccf::kv::untyped::CommitHook wrap_commit_hook(const CommitHook &hook)
Definition map.h:73
static ccf::kv::untyped::MapHook wrap_map_hook(const MapHook &hook)
Definition map.h:80
static ccf::kv::untyped::CommitHook wrap_commit_hook(const CommitHook &hook)
Definition value.h:65
static ccf::kv::untyped::MapHook wrap_map_hook(const MapHook &hook)
Definition value.h:72
std::optional< V > Write
Definition value.h:38
static std::vector< uint8_t > get_entry(const uint8_t *&data, size_t &size)
Definition ledger_enclave.h:26
Definition state_machine.h:15
void expect(T state_) const
Definition state_machine.h:25
void advance(T state_)
Definition state_machine.h:45
bool check(T state_) const
Definition state_machine.h:35
void set_header(std::string k, const std::string &v)
Definition http_builder.h:45
void set_body(const std::vector< uint8_t > *b, bool overwrite_content_length=true)
Definition http_builder.h:72
Definition http_builder.h:117
Definition ring_buffer_types.h:157
StartType
Definition enclave_interface_types.h:92
@ Join
Definition enclave_interface_types.h:94
@ Recover
Definition enclave_interface_types.h:95
@ Start
Definition enclave_interface_types.h:93
#define LOG_INFO_FMT
Definition internal_logger.h:15
#define LOG_TRACE_FMT
Definition internal_logger.h:13
#define LOG_DEBUG_FMT
Definition internal_logger.h:14
#define LOG_FAIL_FMT
Definition internal_logger.h:16
CurveID
Definition curve.h:18
std::vector< uint8_t > raw_from_b64(const std::string_view &b64_string)
Definition base64.cpp:12
ccf::crypto::Pem public_key_pem_from_cert(const std::vector< uint8_t > &der)
Definition verifier.cpp:48
std::string b64url_from_raw(const uint8_t *data, size_t size, bool with_padding=true)
Definition base64.cpp:51
ECKeyPairPtr make_ec_key_pair(CurveID curve_id=service_identity_curve_choice)
Definition ec_key_pair.cpp:530
VerifierPtr make_verifier(const std::vector< uint8_t > &cert)
Definition verifier.cpp:18
std::string get_subject_name(const Pem &cert)
Definition verifier.cpp:53
std::vector< uint8_t > cert_pem_to_der(const Pem &pem)
Definition verifier.cpp:38
std::map< std::string, std::string, std::less<> > HeaderMap
Definition http_header_map.h:10
if(argc !=1)
Definition kv_helpers.h:73
void register_class_ids()
Definition global_class_ids.cpp:17
std::map< ccf::kv::serialisers::SerialisedEntry, std::optional< ccf::kv::serialisers::SerialisedEntry > > Write
Definition untyped.h:16
uint64_t Term
Definition kv_types.h:43
std::unique_ptr< ConsensusHook > ConsensusHookPtr
Definition hooks.h:21
@ SUCCESS
Definition kv_types.h:210
uint64_t Version
Definition version.h:8
ApplyResult
Definition kv_types.h:302
@ PASS_SIGNATURE
Definition kv_types.h:304
@ FAIL
Definition kv_types.h:311
std::vector< ConsensusHookPtr > ConsensusHookPtrs
Definition hooks.h:22
UVMEndorsements verify_uvm_endorsements_descriptor(const std::vector< uint8_t > &uvm_endorsements_raw, const pal::PlatformAttestationMeasurement &uvm_measurement)
Definition uvm_endorsements.cpp:648
std::mutex Mutex
Definition locking.h:12
Task make_basic_task(Ts &&... ts)
Definition basic_task.h:33
void add_periodic_task(Task task, std::chrono::milliseconds initial_delay, std::chrono::milliseconds repeat_period)
Definition task_system.cpp:75
void add_task(Task task)
Definition task_system.cpp:65
std::shared_ptr< BaseTask > Task
Definition task.h:36
Definition app_interface.h:14
LedgerSecretPtr find_and_unseal_ledger_secret_from_disk(const std::string &sealed_secret_dir, kv::Version max_version)
Definition local_sealing.h:191
NodeId compute_node_id_from_kp(const ccf::crypto::ECKeyPairPtr &node_sign_kp)
Definition nodes.h:43
constexpr auto get_actor_prefix(ActorsType at)
Definition actors.h:24
std::shared_ptr< ccf::kv::Store > make_store()
Definition network_tables.h:39
std::vector< uint8_t > CoseSignature
Definition signatures.h:64
std::tuple< NodeStartupState, std::optional< ccf::kv::Version >, std::optional< ccf::kv::Version > > ExtendedState
Definition node_operation_interface.h:20
std::list< EncryptedLedgerSecretInfo > RecoveredEncryptedLedgerSecrets
Definition share_manager.h:158
view
Definition signatures.h:54
std::map< ccf::kv::Version, LedgerSecretPtr > LedgerSecretsMap
Definition ledger_secrets.h:21
@ WAITING_FOR_RECOVERY_SHARES
void reset_data(std::vector< uint8_t > &data)
Definition node_state.h:80
LedgerSecretPtr make_ledger_secret()
Definition ledger_secret.h:81
NodeStartupState
Definition node_startup_state.h:10
llhttp_status http_status
Definition http_status.h:9
QuoteVerificationResult
Definition quote.h:18
std::shared_ptr< LedgerSecret > LedgerSecretPtr
Definition ledger_secret.h:79
constexpr View VIEW_UNKNOWN
Definition tx_id.h:26
uint64_t View
Definition tx_id.h:23
void seal_ledger_secret_to_disk(const std::string &sealed_secret_dir, const ccf::pal::snp::TcbVersionRaw &tcb_version, const kv::Version &version, const LedgerSecretPtr &ledger_secret)
Definition local_sealing.h:107
@ channel_msg
Definition node_types.h:22
@ consensus_msg
Definition node_types.h:23
void to_json(nlohmann::json &j, const ClaimsDigest &hash)
Definition claims_digest.h:49
std::shared_ptr<::http::HttpRpcContext > make_rpc_context(std::shared_ptr< ccf::SessionContext > s, const std::vector< uint8_t > &packed)
Definition http_rpc_context.h:374
Definition perf_client.h:12
Definition consensus_types.h:23
uint64_t Index
Definition ledger_enclave_types.h:11
@ Recovery
Definition ledger_enclave_types.h:15
Definition configuration.h:14
URL parse_url_full(const std::string &url)
Definition http_parser.h:151
std::shared_ptr< AbstractWriter > WriterPtr
Definition ring_buffer_types.h:154
#define RINGBUFFER_WRITE_MESSAGE(MSG,...)
Definition ring_buffer_types.h:259
Definition gov_effects_interface.h:22
std::optional< ccf::crypto::Pem > previous
Definition gov_effects_interface.h:23
ccf::crypto::Pem next
Definition gov_effects_interface.h:24
std::optional< std::string > security_policy
Definition startup_config.h:82
std::optional< std::string > uvm_endorsements
Definition startup_config.h:83
std::optional< std::string > snp_endorsements
Definition startup_config.h:84
ccf::pal::snp::EndorsementsServers snp_endorsements_servers
Definition startup_config.h:73
std::optional< std::string > snp_endorsements_file
Definition startup_config.h:76
Environment environment
Definition startup_config.h:88
ccf::ds::TimeString key_refresh_interval
Definition startup_config.h:65
std::string subject_name
Definition startup_config.h:35
size_t initial_validity_days
Definition startup_config.h:38
ccf::NodeInfoNetwork network
Definition startup_config.h:31
JWT jwt
Definition startup_config.h:69
Attestation attestation
Definition startup_config.h:92
NodeCertificateInfo node_certificate
Definition startup_config.h:42
Definition cose_signatures_config.h:12
Definition node_call_types.h:83
QuoteInfo quote_info
Definition node_call_types.h:85
std::optional< ccf::crypto::Pem > certificate_signing_request
Definition node_call_types.h:88
std::optional< ccf::kv::Version > startup_seqno
Definition node_call_types.h:87
NodeInfoNetwork node_info_network
Definition node_call_types.h:84
nlohmann::json node_data
Definition node_call_types.h:90
ccf::crypto::Pem public_encryption_key
Definition node_call_types.h:86
Definition node_call_types.h:94
std::optional< NetworkInfo > network_info
Definition node_call_types.h:149
NodeStatus node_status
Definition node_call_types.h:95
Definition network_state.h:12
std::shared_ptr< LedgerSecrets > ledger_secrets
Definition network_state.h:14
std::unique_ptr< NetworkIdentity > identity
Definition network_state.h:13
std::shared_ptr< ccf::kv::Store > tables
Definition network_tables.h:46
const JwtIssuers jwt_issuers
Definition network_tables.h:164
const Signatures signatures
Definition network_tables.h:222
Definition node_state.h:75
ccf::crypto::Pem service_cert
Definition node_state.h:77
ccf::crypto::Pem self_signed_node_cert
Definition node_state.h:76
Describes a quote (attestation) from trusted hardware.
Definition quote_info.h:26
QuoteFormat format
Quote format.
Definition quote_info.h:28
std::optional< std::vector< uint8_t > > uvm_endorsements
UVM endorsements (SNP-only)
Definition quote_info.h:34
std::vector< uint8_t > quote
Enclave quote.
Definition quote_info.h:30
std::vector< uint8_t > endorsements
Quote endorsements.
Definition quote_info.h:32
Definition session_metrics.h:13
std::vector< uint8_t > service_cert
Definition startup_config.h:138
bool follow_redirect
Definition startup_config.h:139
ccf::NodeInfoNetwork::NetAddress target_rpc_address
Definition startup_config.h:136
ccf::ds::TimeString retry_timeout
Definition startup_config.h:137
std::optional< std::vector< uint8_t > > previous_service_identity
Definition startup_config.h:145
Definition startup_config.h:106
size_t initial_service_certificate_validity_days
Definition startup_config.h:114
ccf::COSESignaturesConfig cose_signatures
Definition startup_config.h:116
Join join
Definition startup_config.h:141
nlohmann::json node_data
Definition startup_config.h:122
Recover recover
Definition startup_config.h:150
std::string startup_host_time
Definition startup_config.h:110
std::string service_subject_name
Definition startup_config.h:115
Definition consensus_config.h:11
Definition cose_common.h:57
size_t count_s() const
Definition unit_strings.h:197
const std::string & get_name() const
Definition get_name.h:18
Definition attestation_sev_snp_endorsements.h:20
Definition attestation_sev_snp.h:387