Documentation
¶
Index ¶
- Constants
- func AppendHistory(accountsDbDir string, entry StateHistoryEntry) error
- func DeleteState(accountsDbDir string) error
- func PruneHistory(accountsDbDir string) error
- func RecordBootstrap(accountsDbDir string, slot uint64, ...) error
- func RecordCorrupted(accountsDbDir string, slot uint64, ...) error
- func RecordRebuild(accountsDbDir string, slot uint64, ...) error
- func RecordResume(accountsDbDir string, slot uint64, ...) error
- func RecordShutdown(accountsDbDir string, slot uint64, ...) error
- func ValidateAccountsDbArtifacts(accountsDbDir string) error
- type BankhashGetter
- type BlockhashEntry
- type HistoryEvent
- type MithrilState
- func CheckAndLoadValidState(accountsDbDir string) (*MithrilState, error)
- func LoadState(accountsDbDir string) (*MithrilState, error)
- func NewReadyState(snapshotSlot uint64, snapshotEpoch uint64, fullSnapshotPath string, ...) *MithrilState
- func NewReadyStateWithOpts(opts NewReadyStateOpts) *MithrilState
- func (s *MithrilState) GetCurrentSlot() uint64
- func (s *MithrilState) GetResumeSlot() uint64
- func (s *MithrilState) HasResumeData() bool
- func (s *MithrilState) IsCorrupted() bool
- func (s *MithrilState) IsReady() bool
- func (s *MithrilState) IsStale(latestSlot uint64, threshold uint64) bool
- func (s *MithrilState) MarkCorrupted(accountsDbDir string, reason string) error
- func (s *MithrilState) Save(accountsDbDir string) error
- func (s *MithrilState) SetClusterInfo(cluster, genesisHash string)
- func (s *MithrilState) UpdateLastSlot(accountsDbDir string, slot uint64, bankhash []byte) error
- func (s *MithrilState) UpdateOnShutdown(accountsDbDir string, slot uint64, bankhash []byte, ctx *ShutdownContext) error
- func (s *MithrilState) ValidateAgainstBankhashDB(bankhashDb BankhashGetter) error
- func (s *MithrilState) ValidateGenesisHash(expectedGenesisHash string) error
- type NewReadyStateOpts
- type ShutdownContext
- type SlotHashEntry
- type SnapshotInfo
- type StateHistoryEntry
Constants ¶
const ( ShutdownReasonNormal = "graceful shutdown (Ctrl+C)" ShutdownReasonStall = "block fetch stalled - no RPC progress for 5+ minutes" ShutdownReasonLeaderSchedule = "leader schedule fetch failed from all RPC endpoints" ShutdownReasonError = "replay error" // Will be suffixed with actual error ShutdownReasonCompleted = "replay completed - reached end slot" )
Shutdown reason constants - these are stored in the state file and should be human-readable without needing to look up what they mean.
const CurrentStateSchemaVersion uint32 = 1
CurrentStateSchemaVersion is the current version of the state file format. Increment this when making breaking changes to the state file structure.
const HistoryFileName = "mithril_state.history.jsonl"
const MaxHistoryEntries = 500
MaxHistoryEntries is the maximum number of history entries to retain.
const StateFileName = "mithril_state.json"
Variables ¶
This section is empty.
Functions ¶
func AppendHistory ¶
func AppendHistory(accountsDbDir string, entry StateHistoryEntry) error
AppendHistory appends a history entry to the state history file. The history file is append-only JSONL format.
func DeleteState ¶
DeleteState removes the state file from the accountsdb directory.
func PruneHistory ¶
PruneHistory removes old entries if history exceeds MaxHistoryEntries. Should be called on startup to prevent unbounded growth.
func RecordBootstrap ¶
func RecordBootstrap(accountsDbDir string, slot uint64, bankhash, runID, version, commit, branch string) error
RecordBootstrap records a bootstrap event in the history.
func RecordCorrupted ¶
func RecordCorrupted(accountsDbDir string, slot uint64, bankhash, runID, version, commit, branch, reason string) error
RecordCorrupted records a corruption event in the history.
func RecordRebuild ¶
func RecordRebuild(accountsDbDir string, slot uint64, bankhash, version, commit, branch, reason string) error
RecordRebuild records when AccountsDB is about to be cleaned/rebuilt. This should be called BEFORE CleanAccountsDbDir to preserve the history.
func RecordResume ¶
func RecordResume(accountsDbDir string, slot uint64, bankhash, runID, version, commit, branch string) error
RecordResume records a resume event in the history.
func RecordShutdown ¶
func RecordShutdown(accountsDbDir string, slot uint64, bankhash, runID, version, commit, branch, reason string) error
RecordShutdown records a shutdown event in the history.
func ValidateAccountsDbArtifacts ¶
ValidateAccountsDbArtifacts checks if expected AccountsDB artifacts exist. This provides an extra layer of validation beyond just checking the state file.
Types ¶
type BankhashGetter ¶
BankhashGetter is an interface for getting bankhashes by slot. This is used for integrity validation without creating import cycles.
type BlockhashEntry ¶
type BlockhashEntry struct {
Blockhash string `json:"blockhash"`
LamportsPerSignature uint64 `json:"lamports_per_sig"`
}
BlockhashEntry represents a single entry in the RecentBlockhashes sysvar
type HistoryEvent ¶
type HistoryEvent string
HistoryEvent represents the type of state change event.
const ( HistoryEventBootstrap HistoryEvent = "bootstrap" HistoryEventShutdown HistoryEvent = "shutdown" HistoryEventCorrupted HistoryEvent = "corrupted" HistoryEventResume HistoryEvent = "resume" HistoryEventRebuild HistoryEvent = "rebuild" // AccountsDB being cleaned/rebuilt )
type MithrilState ¶
type MithrilState struct {
// =========================================================================
// Schema & Run Lineage
// =========================================================================
StateSchemaVersion uint32 `json:"state_schema_version"`
// Run lineage - tracks the chain of sessions that have used this AccountsDB
RootRunID string `json:"root_run_id,omitempty"` // Run that built AccountsDB from snapshot (never changes)
ParentRunID string `json:"parent_run_id,omitempty"` // Run we resumed from (empty if fresh start)
CurrentRunID string `json:"current_run_id,omitempty"` // Run that last wrote this file
// =========================================================================
// Writer Metadata (who last wrote this file and why they stopped)
// =========================================================================
LastWriterVersion string `json:"last_writer_version,omitempty"` // Semver tag (e.g., "v0.1.0" or "dev")
LastWriterCommit string `json:"last_writer_commit,omitempty"` // Git commit hash of writer binary
LastWriterBranch string `json:"last_writer_branch,omitempty"` // Git branch name (may be empty)
LastShutdownReason string `json:"last_shutdown_reason,omitempty"` // human-readable reason
LastShutdownAt time.Time `json:"last_shutdown_at,omitempty"` // when shutdown occurred
// =========================================================================
// AccountsDB Origin (snapshot info - set once, never changes)
// =========================================================================
Stage string `json:"stage"` // "ready", "downloading", "building", "corrupted"
SnapshotSlot uint64 `json:"snapshot_slot"` // Slot of the snapshot used to build AccountsDB
SnapshotEpoch uint64 `json:"snapshot_epoch,omitempty"` // Epoch of the snapshot
FullSnapshot *SnapshotInfo `json:"full_snapshot,omitempty"` // Full snapshot file info
IncrSnapshot *SnapshotInfo `json:"incr_snapshot,omitempty"` // Incremental snapshot file info
BuildCompleted time.Time `json:"build_completed_at,omitempty"` // When AccountsDB build finished
BuildStartedAt time.Time `json:"build_started_at,omitempty"` // When bootstrap started
BuildMode string `json:"build_mode,omitempty"` // "auto", "snapshot", "new-snapshot", "accountsdb"
Cluster string `json:"cluster,omitempty"` // "mainnet-beta", "testnet", "devnet"
GenesisHash string `json:"genesis_hash,omitempty"` // Base58 genesis hash from RPC
// Corruption tracking - set when integrity check fails
CorruptionReason string `json:"corruption_reason,omitempty"`
CorruptionDetectedAt time.Time `json:"corruption_detected_at,omitempty"`
// =========================================================================
// Current Position (where we left off)
// =========================================================================
LastSlot uint64 `json:"last_slot,omitempty"` // Last successfully replayed slot
LastEpoch uint64 `json:"last_epoch,omitempty"` // Epoch of last replayed slot
LastBankhash string `json:"last_bankhash,omitempty"` // Bankhash of last replayed slot (base58)
// LtHash and fee state
LastAcctsLtHash string `json:"last_accts_lt_hash,omitempty"` // base64 encoded cumulative LtHash
LastLamportsPerSignature uint64 `json:"last_lamports_per_sig,omitempty"` // FeeRateGovernor.LamportsPerSignature
LastPrevLamportsPerSig uint64 `json:"last_prev_lamports_per_sig,omitempty"` // FeeRateGovernor.PrevLamportsPerSignature
LastNumSignatures uint64 `json:"last_num_signatures,omitempty"` // SlotCtx.NumSignatures
// Blockhash context - required because appendvec writes are not fsynced
LastRecentBlockhashes []BlockhashEntry `json:"last_recent_blockhashes,omitempty"` // 150 entries, newest first
LastEvictedBlockhash string `json:"last_evicted_blockhash,omitempty"` // 151st blockhash (base58)
LastBlockhash string `json:"last_blockhash,omitempty"` // Blockhash of last slot (base58)
// SlotHashes context - vote program needs accurate slot→hash mappings
LastSlotHashes []SlotHashEntry `json:"last_slot_hashes,omitempty"` // up to 512 entries, newest first
// ReplayCtx fields - so resume uses fresh values instead of stale manifest
LastCapitalization uint64 `json:"last_capitalization,omitempty"` // Total lamports in circulation
LastSlotsPerYear float64 `json:"last_slots_per_year,omitempty"` // Slots per year for inflation calc
LastInflationInitial float64 `json:"last_inflation_initial,omitempty"` // Inflation parameters
LastInflationTerminal float64 `json:"last_inflation_terminal,omitempty"`
LastInflationTaper float64 `json:"last_inflation_taper,omitempty"`
LastInflationFoundation float64 `json:"last_inflation_foundation,omitempty"`
LastInflationFoundationTerm float64 `json:"last_inflation_foundation_term,omitempty"`
// EpochStakes - computed at epoch boundaries, required for leader schedule on resume
// Key: epoch number (leader schedule epoch), Value: JSON-serialized epoch stakes
// These are NOT loaded from manifest - they are computed during replay and persisted.
ComputedEpochStakes map[uint64]string `json:"computed_epoch_stakes,omitempty"`
// =========================================================================
// Legacy fields - kept for backwards compatibility
// =========================================================================
// TODO: Remove after v1.0 release
LastCommit string `json:"last_commit,omitempty"` // Deprecated: use last_writer_commit
LastRunID string `json:"last_run_id,omitempty"` // Deprecated: use current_run_id
LastRunAt time.Time `json:"last_run_at,omitempty"` // Deprecated: tracked via last_shutdown_at
}
MithrilState tracks the current state of the mithril node. The state file serves as an atomic marker of validity - AccountsDB is valid if and only if this file exists with Stage == "ready".
func CheckAndLoadValidState ¶
func CheckAndLoadValidState(accountsDbDir string) (*MithrilState, error)
CheckAndLoadValidState loads state and validates that AccountsDB is ready. Returns (state, nil) if valid, or (nil, nil) if state is invalid/missing. Returns (nil, error) only for unexpected errors.
func LoadState ¶
func LoadState(accountsDbDir string) (*MithrilState, error)
LoadState loads the state file from the accountsdb directory. Returns nil and no error if the file doesn't exist. Handles migration from older schema versions automatically.
func NewReadyState ¶
func NewReadyState(snapshotSlot uint64, snapshotEpoch uint64, fullSnapshotPath string, incrSnapshotPath string, incrBaseSlot uint64, incrSlot uint64) *MithrilState
NewReadyState creates a new state marking the AccountsDB as ready.
func NewReadyStateWithOpts ¶
func NewReadyStateWithOpts(opts NewReadyStateOpts) *MithrilState
NewReadyStateWithOpts creates a new state with full options including cluster and version info.
func (*MithrilState) GetCurrentSlot ¶
func (s *MithrilState) GetCurrentSlot() uint64
GetCurrentSlot returns the most recent slot (LastSlot if replayed, else SnapshotSlot).
func (*MithrilState) GetResumeSlot ¶
func (s *MithrilState) GetResumeSlot() uint64
GetResumeSlot returns the slot to resume from. Returns LastSlot + 1 if replay has happened, otherwise SnapshotSlot + 1.
func (*MithrilState) HasResumeData ¶
func (s *MithrilState) HasResumeData() bool
HasResumeData returns true if the state has resume context stored. This indicates the state was saved during a graceful shutdown with full context.
func (*MithrilState) IsCorrupted ¶
func (s *MithrilState) IsCorrupted() bool
IsCorrupted returns true if the state indicates AccountsDB is corrupted.
func (*MithrilState) IsReady ¶
func (s *MithrilState) IsReady() bool
IsReady returns true if the state indicates AccountsDB is valid and ready.
func (*MithrilState) IsStale ¶
func (s *MithrilState) IsStale(latestSlot uint64, threshold uint64) bool
IsStale returns true if the state is significantly behind the given slot.
func (*MithrilState) MarkCorrupted ¶
func (s *MithrilState) MarkCorrupted(accountsDbDir string, reason string) error
MarkCorrupted updates the state file to indicate AccountsDB is corrupted. This persists the corruption status so the next startup knows to rebuild.
func (*MithrilState) Save ¶
func (s *MithrilState) Save(accountsDbDir string) error
Save writes the state to the accountsdb directory.
func (*MithrilState) SetClusterInfo ¶
func (s *MithrilState) SetClusterInfo(cluster, genesisHash string)
SetClusterInfo updates the cluster and genesis hash in the state. Should be called on first run after upgrade if genesis hash is missing.
func (*MithrilState) UpdateLastSlot ¶
func (s *MithrilState) UpdateLastSlot(accountsDbDir string, slot uint64, bankhash []byte) error
UpdateLastSlot updates the last slot and bankhash in the state file. This should be called after successfully committing a slot during replay.
func (*MithrilState) UpdateOnShutdown ¶
func (s *MithrilState) UpdateOnShutdown(accountsDbDir string, slot uint64, bankhash []byte, ctx *ShutdownContext) error
UpdateOnShutdown updates the state file with full shutdown context. This handles the run lineage: the current session's RunID becomes CurrentRunID, and if this is a resume, the previous CurrentRunID becomes ParentRunID.
func (*MithrilState) ValidateAgainstBankhashDB ¶
func (s *MithrilState) ValidateAgainstBankhashDB(bankhashDb BankhashGetter) error
ValidateAgainstBankhashDB checks if AccountsDB has been modified beyond state file. This detects cases where the process was killed (Ctrl+Z, kill -9) without updating the state file, leaving AccountsDB in an inconsistent state.
func (*MithrilState) ValidateGenesisHash ¶
func (s *MithrilState) ValidateGenesisHash(expectedGenesisHash string) error
ValidateGenesisHash checks if the stored genesis hash matches the expected value. Returns an error if there's a mismatch (prevents mainnet/testnet mixups). Returns nil if state has no genesis hash stored (first run after upgrade).
type NewReadyStateOpts ¶
type NewReadyStateOpts struct {
SnapshotSlot uint64
SnapshotEpoch uint64
FullSnapshotPath string
IncrSnapshotPath string
IncrBaseSlot uint64
IncrSlot uint64
BuildMode string // "auto", "snapshot", "new-snapshot", "accountsdb"
BuildStartedAt time.Time
Cluster string // "mainnet-beta", "testnet", "devnet"
GenesisHash string // Base58 genesis hash
WriterVersion string // Semver tag
WriterCommit string // Git commit hash
}
NewReadyStateOpts contains options for creating a new ready state.
type ShutdownContext ¶
type ShutdownContext struct {
// Current session's run ID (becomes CurrentRunID in state file)
RunID string
// Writer info
WriterVersion string // Semver tag (e.g., "v0.1.0" or "dev")
WriterCommit string // Git commit hash
WriterBranch string // Git branch name (may be empty if not available)
// Shutdown reason
ShutdownReason string // Why the session ended (see ShutdownReason* constants)
// Epoch of the last replayed slot
Epoch uint64
// LtHash and fee state
AcctsLtHash string // base64 encoded
LamportsPerSignature uint64
PrevLamportsPerSig uint64
NumSignatures uint64
// Blockhash context
RecentBlockhashes []BlockhashEntry // 150 entries, newest first
EvictedBlockhash string // base58 encoded, 151st blockhash
LastBlockhash string // base58 encoded, blockhash of last slot (parent for next)
// SlotHashes context - vote program uses this to verify slot→hash mappings
SlotHashes []SlotHashEntry // up to 512 entries, newest first
// ReplayCtx fields - so resume uses fresh values instead of stale manifest
Capitalization uint64 // Total lamports in circulation
SlotsPerYear float64 // Slots per year for inflation calc
InflationInitial float64
InflationTerminal float64
InflationTaper float64
InflationFoundation float64
InflationFoundationTerm float64
// EpochStakes - computed at epoch boundaries, required for leader schedule on resume
// Key: epoch number, Value: JSON-serialized epoch stakes (as []byte)
ComputedEpochStakes map[uint64][]byte
}
ShutdownContext contains the data to persist on graceful shutdown. This is passed to UpdateOnShutdown to save the current session state.
type SlotHashEntry ¶
SlotHashEntry represents a single entry in the SlotHashes sysvar
type SnapshotInfo ¶
type SnapshotInfo struct {
Path string `json:"path"`
Slot uint64 `json:"slot"`
BaseSlot uint64 `json:"base_slot,omitempty"` // only for incrementals
}
SnapshotInfo contains metadata about a downloaded snapshot file.
type StateHistoryEntry ¶
type StateHistoryEntry struct {
Timestamp time.Time `json:"ts"`
Event HistoryEvent `json:"event"`
Slot uint64 `json:"slot"`
Bankhash string `json:"bankhash,omitempty"`
RunID string `json:"run_id,omitempty"`
Version string `json:"version,omitempty"`
Commit string `json:"commit,omitempty"`
Branch string `json:"branch,omitempty"` // git branch name (may be empty)
Reason string `json:"reason,omitempty"` // shutdown reason or corruption reason
}
StateHistoryEntry represents a single entry in the state history log.
func GetRecentHistory ¶
func GetRecentHistory(accountsDbDir string, n int) ([]StateHistoryEntry, error)
GetRecentHistory returns the N most recent history entries.
func LoadHistory ¶
func LoadHistory(accountsDbDir string) ([]StateHistoryEntry, error)
LoadHistory loads all history entries from the state history file. Returns empty slice if file doesn't exist.