sgns::PruneEligibility¶
Read-only prune-eligibility evaluator (PRUNE-01, GATE-01). More...
#include <PruneEligibility.hpp>
Public Functions¶
| Name | |
|---|---|
| outcome::result< std::shared_ptr< PruneEligibility > > | New(crdt::GlobalDB & globaldb, TransactionManager & transaction_manager, UTXOManager & utxo_manager, NodeType node_type, const PruningConfig & config) Fail-closed factory (the construction gate). |
| std::string | BuildPruneMarkerKey(const std::string & tx_hash) Builds the node-local marker key for tx_hash. |
| outcome::result< std::pair< PrunedLookup, std::optional< SGTransaction::PrunedTransactionRecord > > > | LookupPrunedEntry(crdt::GlobalDB & db, const std::string & tx_hash) Answers "was this transaction's history pruned here?" (D-04). |
| std::pair< base::Buffer, base::Buffer > | BuildPruneMarkerEntry(const std::string & tx_hash, const std::string & resolved_tx_path) Builds the production marker entry for tx_hash (D-C1). |
| outcome::result< void > | WritePrunedEntryForTest(crdt::GlobalDB & db, const std::string & tx_hash, const SGTransaction::PrunedTransactionRecord & record) TEST-ONLY marker writer (the D-04 test seam). |
| bool | IsAllowlistedTxKey(const std::string & key) const THE allowlist (D-C7): exact /bc- |
| outcome::result< PruneEvaluationResult > | Evaluate() const Enumerates and evaluates every candidate (read-only). |
| outcome::result< BlockGateResult > | EvaluateDeltaBlockErasable(const std::string & cid_string, const PruneEvaluationResult & eligible) const THE multi-element block gate (PRUNE-03, D-C3). |
Public Attributes¶
| Name | |
|---|---|
| constexpr std::string_view | PRUNE_MARKER_PREFIX |
Detailed Description¶
Read-only prune-eligibility evaluator (PRUNE-01, GATE-01).
PURE evaluator (D-C6): it runs on committed state only — driven from a timer cycle by the caller, NEVER from CRDT element callbacks (they fire pre-batch-commit). It performs ZERO writes: no Put, no Erase, no staging, no hooks. The Phase-18 TxPruner is the reuse seam — it calls Evaluate() verbatim and owns every mutation.
Gates:
- Construction fails closed unless NodeType is Light (GATE-01 role gate; full/archive never erase history).
- IsAllowlistedTxKey is the ONE allowlist home (D-C7): exact base + "tx/" prefix over monitored networks only, with the trailing slash (a slashless prefix would also match /bc-
/txfoo siblings). - Evaluate fails closed with std::errc::invalid_argument when no finality_window is configured.
- EvaluateDeltaBlockErasable is the PRUNE-03 gate: a block erases only when every element AND tombstone key it carries is eligible and allowlist-conformant, parsed from the block itself (D-C3).
Public Functions Documentation¶
function New¶
static outcome::result< std::shared_ptr< PruneEligibility > > New(
crdt::GlobalDB & globaldb,
TransactionManager & transaction_manager,
UTXOManager & utxo_manager,
NodeType node_type,
const PruningConfig & config
)
Fail-closed factory (the construction gate).
Parameters:
- globaldb Committed-state reader for tx enumeration, priorities, and head height.
- transaction_manager Owner of the tx path/allowlist contracts and the tx->CID map resolution.
- utxo_manager Owner of the outpoint lifecycle (spend discriminator and spender carrier).
- node_type Deployment role of the constructing node.
- config Validated pruning policy.
Return: The evaluator, or outcome::failure for a non-Light role.
Rejects any role other than NodeType::Light with std::errc::operation_not_permitted before any state is read (GATE-01). The PruningConfig default-disabled is the separate consent gate and is NOT re-checked here.
function BuildPruneMarkerKey¶
Builds the node-local marker key for tx_hash.
Parameters:
- tx_hash Transaction hash (readable string form).
Return: "/prune/tx/<tx_hash>".
PRUNE_MARKER_PREFIX + hash; the tx PATH travels inside the record value because lookups are by hash.
function LookupPrunedEntry¶
static outcome::result< std::pair< PrunedLookup, std::optional< SGTransaction::PrunedTransactionRecord > > > LookupPrunedEntry(
crdt::GlobalDB & db,
const std::string & tx_hash
)
Answers "was this transaction's history pruned here?" (D-04).
Parameters:
- db Committed-state reader (marker + value presence).
- tx_hash Transaction hash (readable string form).
Return: (verdict, decoded record when a marker decoded), or outcome::failure for a raw-read/decode/presence error.
Reads the marker at BuildPruneMarkerKey(tx_hash) through the node-local raw surface, then establishes value presence for the record's tx_path through the same CRDT-layer query surface the evaluator enumerates — both reads share one resolution path (T-17-0503). Verdicts: marker ∧ ¬value ⇒ PRUNED (record decoded); ¬marker ∧ ¬value ⇒ NOT_FOUND; marker ∧ value ⇒ VALUE_PRESENT_INVARIANT_VIOLATION (logged at ERROR — never guessed). A malformed marker payload is an error result, never a silent PRUNED (T-17-0502), and a decoded record whose tx_path does not end with the requested tx_hash (the empty-payload degenerate case included) is an invariant-violation error too — never a silent PRUNED and never a whole-store prefix scan (WR-04). Writes nothing.
function BuildPruneMarkerEntry¶
static std::pair< base::Buffer, base::Buffer > BuildPruneMarkerEntry(
const std::string & tx_hash,
const std::string & resolved_tx_path
)
Builds the production marker entry for tx_hash (D-C1).
Parameters:
- tx_hash Transaction hash (readable string form).
- resolved_tx_path The tx path RESOLVED by the caller for this erase — the path whose value the erase targets. The record names THIS path, never a local-network formatting of the hash alone, so the lookup's value-presence probe queries the key the erase actually addressed, whatever monitored network it lives under (WR-02). Must end with
tx_hash(the WR-04 shape).
Return: (marker key buffer, serialized record buffer).
The production twin of WritePrunedEntryForTest: returns the key/value buffer pair — BuildPruneMarkerKey(tx_hash) plus a PrunedTransactionRecord naming resolved_tx_path — instead of writing it. The caller stages the pair into the SAME WriteBatch as the erase, so the value-XOR-marker invariant is established atomically with the erase (one commit: value absent AND marker present, never either alone). The key home and record shape live HERE — callers never rebuild them.
function WritePrunedEntryForTest¶
static outcome::result< void > WritePrunedEntryForTest(
crdt::GlobalDB & db,
const std::string & tx_hash,
const SGTransaction::PrunedTransactionRecord & record
)
TEST-ONLY marker writer (the D-04 test seam).
Parameters:
- db Store receiving the marker.
- tx_hash Transaction hash the marker is keyed by.
- record Marker payload to persist.
Return: outcome::success, or outcome::failure on I/O error.
Note: No production caller may invoke this method.
Serializes record and writes it at the marker key on the node-local raw surface. Production NEVER calls this: the real marker write joins Phase 18's erase WriteBatch so the value-XOR-marker invariant is established atomically with the erase itself.
function IsAllowlistedTxKey¶
THE allowlist (D-C7): exact /bc-
Parameters:
- key Candidate storage key.
Return: true when the key is inside the allowlisted prefix.
True only when key starts with GetBlockChainBase(net) + "tx/" for a net in TransactionManager::GetMonitoredNetworkIDs(). The trailing slash is mandatory (T-17-0401): cert slots, registration paths, proof keys, unmonitored networks, and slashless "txfoo" siblings all fail here.
function Evaluate¶
Enumerates and evaluates every candidate (read-only).
Return: The structured eligible/ineligible report, or outcome::failure(std::errc::invalid_argument) when no finality_window is configured (fail closed — a window without N cannot make anything eligible).
Per monitored network: QueryKeyValues(base + "tx/") (WITH the trailing slash), deserialize each value, then per candidate: genuine-consumption of every output (D-C2), spender resolution with existence BEFORE any priority read, spend_height = MAX spender priority over outputs (the most-recent spend binds), and the window maxHeight − spend_height ≥ finality_window (D-02). The window arithmetic lives HERE and nowhere else. Query or per-entry failures are logged and the scan continues (never aborts); every ineligible candidate carries its PruneReason codes.
function EvaluateDeltaBlockErasable¶
outcome::result< BlockGateResult > EvaluateDeltaBlockErasable(
const std::string & cid_string,
const PruneEvaluationResult & eligible
) const
THE multi-element block gate (PRUNE-03, D-C3).
Parameters:
- cid_string CID of the delta block to gate.
- eligible Evaluation whose eligible set (PRUNE-01 verdicts) the carried keys are matched against.
Return: The block verdict (erasable=false with reasons on any miss or parse failure).
Parses the delta block cid_string itself, at evaluation time, via GlobalDB::GetLocalDeltaKeys (elements AND tombstones; "what this node applied" is forbidden as an oracle — light nodes store elements they never applied). The block is erasable only when EVERY carried key is (a) IsAllowlistedTxKey-true and (b) present in eligible's eligible set (matched by tx path). A non-conformant key reports OUT_OF_PREFIX; an allowlisted key outside the eligible set reports NON_ELIGIBLE_SIBLING (an elements-only gate would miss tombstone keys — Pitfall 4). Parse failure fails closed: a not-erasable result carrying DESERIALIZE_FAILED, never a crash and never a guess. Read-only; writes nothing.
Public Attributes Documentation¶
variable PRUNE_MARKER_PREFIX¶
Node-local marker key namespace (CRDTWorkJournal prefix discipline: same shared RocksDB, direct datastore writes, never broadcast).
Updated on 2026-10-22 at 19:28:22 +0000