Skip to content

trustedpeer/GenesisManifest.cpp

Namespaces

Name
sgns
sgns::trustedpeer

Functions

Name
sgns::securecrdt::CandidateCore GenesisCandidateCore(const GenesisManifest & manifest, const std::vector< uint8_t > & canonical_bytes, const std::string & fingerprint, const std::string & domain ="trusted-peer-genesis")

Functions Documentation

function GenesisCandidateCore

sgns::securecrdt::CandidateCore GenesisCandidateCore(
    const GenesisManifest & manifest,
    const std::vector< uint8_t > & canonical_bytes,
    const std::string & fingerprint,
    const std::string & domain ="trusted-peer-genesis"
)

Single construction site of the genesis CandidateCore; the core bytes are the signed genesis proof everywhere, so duplicate constructions drift apart.

Source code

#include "trustedpeer/GenesisManifest.hpp"

#include <algorithm>

#include <gsl/span>

#include "base/hexutil.hpp"
#include "securecrdt/QuorumThresholdValidation.hpp"
#include "trustedpeer/CanonicalTrustCodec.hpp"

namespace sgns::trustedpeer
{
    std::optional<GenesisManifest> GenesisManifest::Canonicalized() const
    {
        if ( encoding_version != ENCODING_VERSION || policy_version != 1 ||
             initial_burn_basis_points != INITIAL_BURN_BASIS_POINTS )
        {
            return std::nullopt;
        }

        const auto bootstrapper     = CanonicalTrustCodec::DecodePublicKey( bootstrapper_public_key );
        const auto normalized_peers = CanonicalTrustCodec::NormalizePublicKeys( peers );
        if ( !bootstrapper || !normalized_peers )
        {
            return std::nullopt;
        }

        const uint64_t peer_count       = normalized_peers->size();
        const uint64_t membership_floor = sgns::securecrdt::MembershipQuorumFloor( peer_count );
        const uint64_t burn_floor       = sgns::securecrdt::BurnQuorumFloor( peer_count );
        if ( membership_threshold < membership_floor || membership_threshold > peer_count ||
             burn_threshold < burn_floor || burn_threshold > peer_count )
        {
            return std::nullopt;
        }

        GenesisManifest canonical         = *this;
        canonical.bootstrapper_public_key = CanonicalTrustCodec::EncodePublicKey(
            gsl::span<const uint8_t>( bootstrapper->data(), bootstrapper->size() ) );
        canonical.peers = *normalized_peers;
        return canonical;
    }

    std::optional<std::vector<uint8_t>> GenesisManifest::CanonicalBytes() const
    {
        const auto canonical = Canonicalized();
        if ( !canonical )
        {
            return std::nullopt;
        }

        const auto bootstrapper = CanonicalTrustCodec::DecodePublicKey( canonical->bootstrapper_public_key );
        if ( !bootstrapper )
        {
            return std::nullopt;
        }

        CanonicalTrustCodec::Writer writer;
        writer.WriteBytes( CanonicalTrustCodec::GENESIS_DOMAIN );
        writer.WriteU8( canonical->encoding_version );
        writer.WriteU16( canonical->network_id );
        if ( !writer.WriteLengthPrefixedBytes(
                 gsl::span<const uint8_t>( bootstrapper->data(), bootstrapper->size() ) ) )
        {
            return std::nullopt;
        }
        writer.WriteU64( canonical->policy_version );
        writer.WriteU32( static_cast<uint32_t>( canonical->peers.size() ) );
        for ( const auto &peer : canonical->peers )
        {
            const auto decoded_peer = CanonicalTrustCodec::DecodePublicKey( peer );
            if ( !decoded_peer || !writer.WriteLengthPrefixedBytes(
                                      gsl::span<const uint8_t>( decoded_peer->data(), decoded_peer->size() ) ) )
            {
                return std::nullopt;
            }
        }
        writer.WriteU64( canonical->membership_threshold );
        writer.WriteU64( canonical->burn_threshold );
        writer.WriteU64( canonical->initial_burn_basis_points );
        return writer.Take();
    }

    std::optional<std::string> GenesisManifest::Fingerprint() const
    {
        const auto bytes = CanonicalBytes();
        if ( !bytes )
        {
            return std::nullopt;
        }
        return CanonicalTrustCodec::Sha256Hex( gsl::span<const uint8_t>( bytes->data(), bytes->size() ) );
    }

    std::optional<GenesisManifest> GenesisManifest::DecodeCanonical( const std::vector<uint8_t> &bytes )
    {
        CanonicalTrustCodec::Reader reader( gsl::span<const uint8_t>( bytes.data(), bytes.size() ) );
        const auto                  domain = reader.ReadBytes( CanonicalTrustCodec::GENESIS_DOMAIN.size() );
        if ( !domain || !std::equal( domain->begin(), domain->end(), CanonicalTrustCodec::GENESIS_DOMAIN.begin() ) )
        {
            return std::nullopt;
        }

        const auto encoding     = reader.ReadU8();
        const auto network      = reader.ReadU16();
        const auto bootstrapper = reader.ReadLengthPrefixedBytes( CanonicalTrustCodec::PUBLIC_KEY_BYTES );
        const auto policy       = reader.ReadU64();
        const auto peer_count   = reader.ReadU32();
        if ( !encoding || *encoding != ENCODING_VERSION || !network || !bootstrapper ||
             bootstrapper->size() != CanonicalTrustCodec::PUBLIC_KEY_BYTES || !policy || !peer_count ||
             *peer_count == 0 || *peer_count > CanonicalTrustCodec::MAX_TRUSTED_PEERS )
        {
            return std::nullopt;
        }

        std::vector<std::string> decoded_peers;
        decoded_peers.reserve( *peer_count );
        for ( uint32_t index = 0; index < *peer_count; ++index )
        {
            const auto peer = reader.ReadLengthPrefixedBytes( CanonicalTrustCodec::PUBLIC_KEY_BYTES );
            if ( !peer || peer->size() != CanonicalTrustCodec::PUBLIC_KEY_BYTES )
            {
                return std::nullopt;
            }
            decoded_peers.push_back(
                CanonicalTrustCodec::EncodePublicKey( gsl::span<const uint8_t>( peer->data(), peer->size() ) ) );
        }

        const auto membership   = reader.ReadU64();
        const auto burn         = reader.ReadU64();
        const auto initial_burn = reader.ReadU64();
        if ( !membership || !burn || !initial_burn || !reader.Exhausted() )
        {
            return std::nullopt;
        }

        GenesisManifest manifest;
        manifest.encoding_version        = *encoding;
        manifest.network_id              = *network;
        manifest.bootstrapper_public_key = CanonicalTrustCodec::EncodePublicKey(
            gsl::span<const uint8_t>( bootstrapper->data(), bootstrapper->size() ) );
        manifest.policy_version            = *policy;
        manifest.peers                     = std::move( decoded_peers );
        manifest.membership_threshold      = *membership;
        manifest.burn_threshold            = *burn;
        manifest.initial_burn_basis_points = *initial_burn;

        const auto canonical = manifest.Canonicalized();
        if ( !canonical || canonical->peers != manifest.peers )
        {
            return std::nullopt;
        }
        const auto canonical_bytes = canonical->CanonicalBytes();
        if ( !canonical_bytes || *canonical_bytes != bytes )
        {
            return std::nullopt;
        }
        return canonical;
    }

    std::optional<GenesisManifest> GenesisManifest::DecodeAndVerify( const std::vector<uint8_t> &bytes,
                                                                     const std::string          &expected_fingerprint )
    {
        const bool canonical_fingerprint =
            expected_fingerprint.size() == 64 && sgns::base::IsLowerHex( expected_fingerprint );
        if ( !canonical_fingerprint )
        {
            return std::nullopt;
        }

        const auto manifest = DecodeCanonical( bytes );
        if ( !manifest || CanonicalTrustCodec::Sha256Hex( gsl::span<const uint8_t>( bytes.data(), bytes.size() ) ) !=
                              expected_fingerprint )
        {
            return std::nullopt;
        }
        return manifest;
    }

    sgns::securecrdt::CandidateCore GenesisCandidateCore( const GenesisManifest      &manifest,
                                                          const std::vector<uint8_t> &canonical_bytes,
                                                          const std::string          &fingerprint,
                                                          const std::string          &domain )
    {
        return { sgns::securecrdt::CandidateCore::ENCODING_VERSION,
                 domain,
                 manifest.network_id,
                 sgns::securecrdt::CandidateKind::TrustedPeerGenesis,
                 manifest.policy_version,
                 fingerprint,
                 fingerprint,
                 canonical_bytes };
    }

    bool GenesisManifest::operator==( const GenesisManifest &other ) const
    {
        return encoding_version == other.encoding_version && network_id == other.network_id &&
               bootstrapper_public_key == other.bootstrapper_public_key && policy_version == other.policy_version &&
               peers == other.peers && membership_threshold == other.membership_threshold &&
               burn_threshold == other.burn_threshold && initial_burn_basis_points == other.initial_burn_basis_points;
    }
} // namespace sgns::trustedpeer

Updated on 2026-09-25 at 15:46:12 +0000