Skip to content

sgns::securecrdt::SecureCrdt

Mandatory wrapper for reading/writing registered SecureCrdt keys. More...

#include <SecureCrdt.hpp>

Inherits from std::enable_shared_from_this< SecureCrdt >

Public Types

Name
enum class uint8_t Error { UNREGISTERED_KEY = 0, NO_VALUE_PROPOSED, INVALID_SIGNATURE, MALFORMED_VALUE}
Error codes returned by SecureCrdt's write/read operations.

Public Functions

Name
SecureCrdt(std::shared_ptr< sgns::crdt::GlobalDB > db, std::string topic)
Constructs a SecureCrdt wrapper over an existing GlobalDB instance.
outcome::result< void > ProposeValue(const sgns::crdt::HierarchicalKey & base_key, const std::vector< uint8_t > & payload)
Proposes a value for a registered base_key. Runs the SAME codec/semantic check the remote filter callback runs on a base_key element (DeserializeFromBytes + Verify) BEFORE ever calling Put – closes the local/remote asymmetry gap (T-09-10). Proposing a value has no signature requirement by itself; it only becomes trusted once quorum-worth of sig-entries exist (D-04), so this is not a bypass of D-03.
outcome::result< void > AddSignature(const sgns::crdt::HierarchicalKey & base_key, const std::string & signer_address, const std::vector< uint8_t > & signature)
Adds a signature over the CURRENT value at base_key. Fetches the value fresh via GlobalDB::Get each call (never a cached/stale value, closing the replay threat T-09-07) and verifies it via multisig::VerifyPayloadSignature before ever calling Put – an invalid signature is never persisted (D-03 local-write gate).
outcome::result< std::optional< sgns::base::Buffer > > ReadIfQuorum(const sgns::crdt::HierarchicalKey & base_key)
Returns the current value at base_key only once the required number of valid unique signatures from the registered signer set are present (D-04 quorum re-derivation); returns std::nullopt if quorum is not yet met.
bool RegisterFilters()
Self-registration entry point: registers the element filter (D-03 second, independent enforcement layer for remote- originated deltas) for every currently-registered SecureCrdtRegistry entry. Must be called once after construction (e.g. from a New(...)-style factory), mirroring ValidatorRegistry::RegisterFilter's call-from-factory convention.

Detailed Description

class sgns::securecrdt::SecureCrdt;

Mandatory wrapper for reading/writing registered SecureCrdt keys.

   `ProposeValue`/`AddSignature` are the only sanctioned callers of
   `GlobalDB::Put` for a registered key (D-03). `ReadIfQuorum` never
   writes and always re-derives trust from the current base_key value
   plus all `sig/<addr>` children (D-04) -- no "final" marker key is
   ever written or read by this class.

Public Types Documentation

enum Error

Enumerator Value Description
UNREGISTERED_KEY 0 base_key has no SecureCrdtRegistry entry
NO_VALUE_PROPOSED AddSignature/ReadIfQuorum called before any ProposeValue.
INVALID_SIGNATURE signature failed VerifyPayloadSignature against the current value
MALFORMED_VALUE payload failed DeserializeFromBytes/Verify (codec/semantic check)

Error codes returned by SecureCrdt's write/read operations.

Public Functions Documentation

function SecureCrdt

SecureCrdt(
    std::shared_ptr< sgns::crdt::GlobalDB > db,
    std::string topic
)

Constructs a SecureCrdt wrapper over an existing GlobalDB instance.

Parameters:

  • db GlobalDB instance to Put/Get/Query against.
  • topic CRDT broadcast/listen topic to use for all Put calls (no new networking – reuses whatever topic the caller's GlobalDB is already wired to).

function ProposeValue

outcome::result< void > ProposeValue(
    const sgns::crdt::HierarchicalKey & base_key,
    const std::vector< uint8_t > & payload
)

Proposes a value for a registered base_key. Runs the SAME codec/semantic check the remote filter callback runs on a base_key element (DeserializeFromBytes + Verify) BEFORE ever calling Put – closes the local/remote asymmetry gap (T-09-10). Proposing a value has no signature requirement by itself; it only becomes trusted once quorum-worth of sig-entries exist (D-04), so this is not a bypass of D-03.

Parameters:

  • base_key Registered CRDT key to propose a value for.
  • payload Raw payload bytes to persist.

Return: outcome::success on success, Error::UNREGISTERED_KEY if base_key has no registry entry, Error::MALFORMED_VALUE if the codec/semantic check fails (Put is never called in that case).

function AddSignature

outcome::result< void > AddSignature(
    const sgns::crdt::HierarchicalKey & base_key,
    const std::string & signer_address,
    const std::vector< uint8_t > & signature
)

Adds a signature over the CURRENT value at base_key. Fetches the value fresh via GlobalDB::Get each call (never a cached/stale value, closing the replay threat T-09-07) and verifies it via multisig::VerifyPayloadSignature before ever calling Put – an invalid signature is never persisted (D-03 local-write gate).

Parameters:

  • base_key Registered CRDT key the signature is claimed over.
  • signer_address Address claimed to have produced signature.
  • signature Raw signature bytes.

Return: outcome::success on success, Error::UNREGISTERED_KEY if base_key has no registry entry, Error::NO_VALUE_PROPOSED if no value exists yet at base_key, Error::INVALID_SIGNATURE if verification fails (Put is never called in that case).

function ReadIfQuorum

outcome::result< std::optional< sgns::base::Buffer > > ReadIfQuorum(
    const sgns::crdt::HierarchicalKey & base_key
)

Returns the current value at base_key only once the required number of valid unique signatures from the registered signer set are present (D-04 quorum re-derivation); returns std::nullopt if quorum is not yet met.

Parameters:

  • base_key Registered CRDT key to read.

Return: outcome::success(bytes) if quorum is met, outcome::success(nullopt) if the key does not exist yet or quorum is not yet met, or Error::UNREGISTERED_KEY if base_key has no registry entry.

Note: This method deliberately does NOT deserialize, semantically- verify, or Apply() the returned bytes. Once quorum is confirmed, the CALLER is responsible for instantiating its own ISignedCRDTData implementer via DeserializeFromBytes(*result) and calling Verify()+Apply() on it. SecureCrdt stays generic across all registered types and never assumes which concrete ISignedCRDTData subclass or Apply() side effect applies to a given base_key – that knowledge lives only with the registered type's own owner (e.g. Phase 10 TrustedPeerRegistry, Phase 11 BurnConfig, Phase 12 ValidatorRegistry migration).

function RegisterFilters

bool RegisterFilters()

Self-registration entry point: registers the element filter (D-03 second, independent enforcement layer for remote- originated deltas) for every currently-registered SecureCrdtRegistry entry. Must be called once after construction (e.g. from a New(...)-style factory), mirroring ValidatorRegistry::RegisterFilter's call-from-factory convention.

Return: true if all filter registrations succeeded.


Updated on 2026-08-06 at 13:59:18 +0000