Skip to content

title: networkregistry/NetworkRegistry.hpp summary: SecureCRDT-backed per-privateNetworkId membership registry (D-06). A child trust domain whose bootstrap record is signed by a majority of the GLOBAL TrustedPeerRegistry and which, once confirmed, governs itself from its own cached member set and quorum a single member can never admit itself unilaterally. Built entirely on the existing SecureCrdt/SecureCrdtRegistry/ ISignedCRDTData machinery (no bespoke signature protocol), mirroring the TrustedPeerRegistry lifecycle (Pattern 3). Serialized records carry ONLY non-secret metadata (D-03): the libp2p PeerId allow-list (consumed by the 15-05 connection gater), the member signing addresses, and key version/ fingerprint never raw private-network credential material.


networkregistry/NetworkRegistry.hpp

SecureCRDT-backed per-privateNetworkId membership registry (D-06). A child trust domain whose bootstrap record is signed by a majority of the GLOBAL TrustedPeerRegistry and which, once confirmed, governs itself from its own cached member set and quorum – a single member can never admit itself unilaterally. Built entirely on the existing SecureCrdt/SecureCrdtRegistry/ ISignedCRDTData machinery (no bespoke signature protocol), mirroring the TrustedPeerRegistry lifecycle (Pattern 3). Serialized records carry ONLY non-secret metadata (D-03): the libp2p PeerId allow-list (consumed by the 15-05 connection gater), the member signing addresses, and key version/ fingerprint – never raw private-network credential material. More...

Namespaces

Name
sgns
sgns::crdt
sgns::networkregistry

Classes

Name
class sgns::networkregistry::NetworkMembershipPayload
ISignedCRDTData payload type carrying a private network's membership record. Serialization is an explicit line-based field layout (see NetworkRegistry.cpp); every field is non-secret metadata (D-03) – the raw pnet credential is NEVER stored.
class sgns::networkregistry::NetworkRegistry
Per-privateNetworkId membership registry (D-06): a child trust domain of the global TrustedPeerRegistry. Delegates ALL signature/quorum logic to SecureCrdt/SecureCrdtRegistry.

Detailed Description

SecureCRDT-backed per-privateNetworkId membership registry (D-06). A child trust domain whose bootstrap record is signed by a majority of the GLOBAL TrustedPeerRegistry and which, once confirmed, governs itself from its own cached member set and quorum – a single member can never admit itself unilaterally. Built entirely on the existing SecureCrdt/SecureCrdtRegistry/ ISignedCRDTData machinery (no bespoke signature protocol), mirroring the TrustedPeerRegistry lifecycle (Pattern 3). Serialized records carry ONLY non-secret metadata (D-03): the libp2p PeerId allow-list (consumed by the 15-05 connection gater), the member signing addresses, and key version/ fingerprint – never raw private-network credential material.

Date: 2026-09-01 Henrique A. Klein ([email protected])

Source code

#ifndef SGNS_NETWORKREGISTRY_NETWORKREGISTRY_HPP
#define SGNS_NETWORKREGISTRY_NETWORKREGISTRY_HPP

#include <atomic>
#include <condition_variable>
#include <cstdint>
#include <memory>
#include <mutex>
#include <optional>
#include <shared_mutex>
#include <string>
#include <string_view>
#include <thread>
#include <vector>

#include "base/logger.hpp"
#include "crdt/hierarchical_key.hpp"
#include "outcome/outcome.hpp"
#include "peerregistry/PeerRegistry.hpp"
#include "securecrdt/ISignedCRDTData.hpp"
#include "securecrdt/SecureCrdt.hpp"
#include "securecrdt/SecureCrdtRegistry.hpp"
#include "trustedpeer/TrustedPeerRegistry.hpp"

namespace sgns::crdt
{
    class GlobalDB; // change-callback registration only (BurnConfig pattern)
} // namespace sgns::crdt

namespace sgns::networkregistry
{
    class NetworkMembershipPayload : public sgns::securecrdt::ISignedCRDTData
    {
    public:
        static constexpr std::string_view MAGIC = "SGNS-NETREG-1";

        NetworkMembershipPayload() = default;

        NetworkMembershipPayload( std::vector<std::string> peers,
                                  std::vector<std::string> signers,
                                  uint32_t                pnet_key_version = 1,
                                  std::string             pnet_key_fingerprint = {} );

        static std::optional<NetworkMembershipPayload> FromBytes( const std::vector<uint8_t> &bytes );

        std::vector<uint8_t> SerializeToBytes() const override;
        bool DeserializeFromBytes( const std::vector<uint8_t> &bytes ) override;
        bool Verify( const std::vector<uint8_t> &payload ) const override;
        void Apply() override;

        const std::vector<std::string> &GetNetworkPeers() const
        {
            return network_peers;
        }

        const std::vector<std::string> &GetNetworkSigners() const
        {
            return network_signers;
        }

        uint32_t GetPnetKeyVersion() const
        {
            return pnet_key_version;
        }

        const std::string &GetPnetKeyFingerprint() const
        {
            return pnet_key_fingerprint;
        }

        // Payload fields -- public so tests / seeders can construct records
        // directly. NOTHING except these non-secret metadata fields may ever
        // be serialized into a membership record (D-03).
        std::vector<std::string> network_peers;     
        std::vector<std::string> network_signers;   
        uint32_t                 pnet_key_version = 1; 
        std::string              pnet_key_fingerprint; 
    };

    class NetworkRegistry : public std::enable_shared_from_this<NetworkRegistry>,
                            public sgns::peerregistry::PeerRegistry
    {
    public:
        NetworkRegistry( std::shared_ptr<sgns::securecrdt::SecureCrdt>           secure_crdt,
                         std::shared_ptr<sgns::trustedpeer::TrustedPeerRegistry> global_trusted_peers,
                         std::string                                            private_network_id,
                         std::vector<std::string>                               initial_network_peers,
                         uint64_t                                               network_quorum_threshold,
                         std::vector<std::string>                               initial_network_signers,
                         std::string                                            pnet_key_fingerprint,
                         sgns::crdt::HierarchicalKey                            base_key,
                         std::shared_ptr<sgns::crdt::GlobalDB>                   global_db = nullptr );

        ~NetworkRegistry();

        static outcome::result<std::shared_ptr<NetworkRegistry>> New(
            std::shared_ptr<sgns::securecrdt::SecureCrdt>           secure_crdt,
            std::shared_ptr<sgns::trustedpeer::TrustedPeerRegistry> global_trusted_peers,
            std::string                                            private_network_id,
            std::vector<std::string>                               initial_network_peers,
            uint64_t                                               network_quorum_threshold,
            std::vector<std::string> initial_network_signers       = {},
            std::string              pnet_key_fingerprint          = {},
            std::shared_ptr<sgns::crdt::GlobalDB> global_db         = nullptr );

        static sgns::crdt::HierarchicalKey DefaultBaseKey( const std::string &private_network_id );

        outcome::result<void> SeedBootstrap( const std::vector<std::string> &initial_network_peers );

        outcome::result<void> ProposeMembershipChange( const std::vector<std::string> &new_peers,
                                                       const std::vector<std::string> &new_signers = {} );

        outcome::result<void> SignMembershipChange( const std::string          &signer_address,
                                                    const std::vector<uint8_t> &signature );

        outcome::result<bool> TryConfirm();

        outcome::result<sgns::securecrdt::SignerSetSnapshot> CurrentSignerSet() const override;

        std::vector<std::string> GetCurrentPeers() const override;

        sgns::crdt::HierarchicalKey BaseKey() const override
        {
            return base_key_;
        }

        bool IsBootstrapConfirmed() const;

        uint64_t RefreshAttemptsForTesting() const;

        void Unregister();

    private:
        bool RegisterSignerSetSource();

        bool RegisterCrdtChangeCallback();

        void RefreshLoop();

        outcome::result<sgns::securecrdt::SignerSetSnapshot> ResolveSignerSet() const;

        std::shared_ptr<sgns::securecrdt::SecureCrdt>           secure_crdt_;
        std::shared_ptr<sgns::trustedpeer::TrustedPeerRegistry> global_trusted_peers_;
        sgns::crdt::HierarchicalKey                            base_key_;
        uint64_t                                               network_quorum_threshold_;

        // TPR bootstrap authority snapshotted at construction (D-06): the
        // signer set authorizing the FIRST membership record.
        std::vector<std::string> tpr_bootstrap_peers_;
        uint64_t                 tpr_majority_threshold_;

        mutable std::shared_mutex cache_mutex_;
        std::vector<std::string>  cached_network_peers_; 
        std::vector<std::string>  cached_network_signers_; 
        bool                      bootstrap_confirmed_ = false;
        int                       registry_token_     = 0;

        std::string                         pnet_key_fingerprint_;
        std::string                         private_network_id_;
        std::shared_ptr<sgns::crdt::GlobalDB> global_db_;
        std::string                         change_callback_pattern_;

        // Change-callback refresh machinery: the datastore callback only
        // flags + notifies; the refresh thread runs TryConfirm outside any
        // datastore callback (re-entrancy guard -- see
        // RegisterCrdtChangeCallback).
        std::thread             refresh_thread_;
        std::mutex              refresh_mutex_;
        std::condition_variable refresh_cv_;
        std::atomic<bool>       refresh_pending_{ false };
        std::atomic<bool>       refresh_stopping_{ false };
        std::atomic<uint64_t>   refresh_attempts_{ 0 };

        sgns::base::Logger logger_ = sgns::base::createLogger( "networkregistry" );
    };
} // namespace sgns::networkregistry

#endif // SGNS_NETWORKREGISTRY_NETWORKREGISTRY_HPP

Updated on 2026-10-06 at 13:34:21 +0000