title: transaction/TxPruner.hpp summary: PRUNE-04 real prune-cycle service: the first production eraser.
transaction/TxPruner.hpp¶
PRUNE-04 real prune-cycle service: the first production eraser. More...
Namespaces¶
| Name |
|---|
| sgns |
| sgns::crdt |
Classes¶
| Name | |
|---|---|
| struct | sgns::PruneCycleStats Counters of ONE prune cycle (RECL-03; counts only). |
| struct | sgns::PruneStatus Queryable pruning status (RECL-04). |
| class | sgns::TxPruner The real prune-cycle service (PRUNE-04). |
Detailed Description¶
PRUNE-04 real prune-cycle service: the first production eraser.
Date: 2026-10-21
Owns the idempotent, crash-consistent erase CYCLE and nothing else: tick gate (Light node, TransactionManager READY, empty missing set, settle window elapsed — D-C2), a per-cycle PruneEligibility::Evaluate() reused VERBATIM (the window arithmetic's one home — never re-implemented here), a block-grouped K-bounded erase budget taken whole or deferred whole (D-04 / Pitfall 1 — same-block siblings are never stranded behind an exhausted K), a FRESH per-outpoint spent-ness re-verify immediately before every erase (D-01), the atomic per-tx erase driver TransactionManager::EraseTransactionEntryPruned (value XOR marker in one commit, 18-03), and the per-cycle observability contract (RECL-03 log + RECL-04 queryable PruneStatus).
Deliberately NOT a GeniusNode member or lambda (the god-class drift the milestone research forbids): the service depends on the transaction/crdt/account-service CONTRACTS only, and every CRDT/service dependency is passed PER CYCLE (D-C4) — the instance holds only config, the node role, the mutex-guarded PruneStatus, and the settle clock, so it is generation-safe to keep alive across Phase-13 account switches. There is no persistent cursor and no cached evaluator: erased transactions vanish from enumeration, so the next evaluation simply stops proposing them.
Source code¶
#ifndef _SGNS_TX_PRUNER_HPP_
#define _SGNS_TX_PRUNER_HPP_
#include <chrono>
#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <system_error>
#include "account/NodeType.hpp"
#include "base/logger.hpp"
#include "outcome/outcome.hpp"
#include "transaction/PruneEligibility.hpp"
namespace sgns
{
namespace crdt
{
class GlobalDB;
}
class TransactionManager;
class UTXOManager;
struct PruneCycleStats
{
uint64_t examined = 0;
uint64_t eligible = 0;
uint64_t erased = 0;
uint64_t held_blocks = 0;
uint64_t skipped = 0;
uint64_t errors = 0;
uint64_t duration_ms = 0;
uint64_t generation = 0;
bool generation_superseded = false;
};
struct PruneStatus
{
std::optional<uint64_t> watermark;
PruneCycleStats last_cycle;
};
class TxPruner
{
public:
static outcome::result<std::shared_ptr<TxPruner>> New( NodeType node_type, const PruningConfig &config );
outcome::result<PruneCycleStats> RunCycle( crdt::GlobalDB &globaldb,
TransactionManager &transaction_manager,
UTXOManager &utxo_manager,
uint64_t generation );
PruneStatus GetPruneStatus() const;
static bool IsPermanentStop( const std::error_code &error );
static constexpr int kInterruptAfterEvaluation = 1;
static constexpr int kInterruptBeforeErase = 2;
static constexpr int kInterruptBeforeStatus = 3;
static constexpr int kInterruptAfterStatus = 4;
static void SetCycleInterruptHookForTest( std::function<bool( int step )> hook );
private:
TxPruner( NodeType node_type, PruningConfig config );
void RecordCompletedCycle( crdt::GlobalDB &globaldb,
PruneCycleStats &stats,
std::chrono::steady_clock::time_point cycle_start );
bool TickGateSettled( TransactionManager &transaction_manager, std::chrono::steady_clock::time_point now );
bool OutputsRemainGenuinelyConsumed( crdt::GlobalDB &globaldb,
UTXOManager &utxo_manager,
const PruneCandidateResult &candidate ) const;
static bool InterruptRequested( int step );
PruningConfig config_m;
NodeType node_type_m;
mutable std::mutex status_mutex_;
PruneStatus status_m;
std::optional<std::chrono::steady_clock::time_point> gate_held_since_;
static std::function<bool( int step )> cycle_interrupt_hook_for_test_;
base::Logger logger_ = base::createLogger( "TxPruner" );
};
} // namespace sgns
#endif
Updated on 2026-10-22 at 19:28:25 +0000