Documentation
¶
Overview ¶
Package rewardstate holds reward_live_stake and reward snapshot metadata query logic shared by the sqlite, mysql, and postgres metadata plugins. The SQL is identical across backends except for a handful of dialect literals (integer cast type, "transaction" table quoting, boolean literals, and whether a bound parameter needs an explicit cast). Those literals are defined once in internal/sqldialect and exposed here through the thin wrappers below, so this package cannot drift from internal/stakequery and internal/accounthistory when a backend is added or corrected.
Index ¶
- func AddStakeRef(refs map[string]CredentialSlotRef, ref models.StakeCredentialRef, slot uint64)
- func CreditLiveStakeDelta(db *gorm.DB, ref models.StakeCredentialRef, amount uint64, slot uint64) (bool, error)
- func CurrentTipSlot(db *gorm.DB) (uint64, error)
- func DeleteStateAfterSlot(db *gorm.DB, slot uint64, txn types.Txn) error
- func DeleteStateBeforeEpoch(db *gorm.DB, epoch uint64, txn types.Txn) error
- func GetAdaPots(db *gorm.DB, epoch uint64) (*models.RewardAdaPots, error)
- func GetPoolInputs(db *gorm.DB, epoch uint64) ([]*models.RewardPoolInput, error)
- func GetSnapshot(db *gorm.DB, epoch uint64, snapshotType string) (*models.RewardSnapshot, error)
- func GroupRefsBySlot(refs map[string]CredentialSlotRef) (map[uint64][]models.StakeCredentialRef, error)
- func LiveStakeNeedsBackfill(db *gorm.DB) (bool, error)
- func RebuildLiveStake(db *gorm.DB, slot uint64, utxoJoinHint string) error
- func RefreshLiveStakeAggregate(db *gorm.DB, ref models.StakeCredentialRef, slot uint64, ...) error
- func SaveAdaPots(db *gorm.DB, pots *models.RewardAdaPots) error
- func SavePoolInputs(db *gorm.DB, inputs []*models.RewardPoolInput) error
- func SaveSnapshot(db *gorm.DB, snapshot *models.RewardSnapshot) error
- func StakeRefsFromLiveUtxoIDs(db *gorm.DB, utxos []models.UtxoId, slot uint64, chunkSize int) (map[string]CredentialSlotRef, error)
- func StakeRefsFromUtxoIDs(db *gorm.DB, utxos []models.UtxoId, slot uint64, chunkSize int) (map[string]CredentialSlotRef, error)
- func StakeRefsFromUtxoSpends(db *gorm.DB, spends []UtxoSpendRef, chunkSize int) (map[string]CredentialSlotRef, error)
- func ValidateLiveStakeRef(ref models.StakeCredentialRef) error
- func ValidateLiveStakeSourceCredentials(db *gorm.DB) error
- type CredentialSlotRef
- type PoolDelegationCache
- type PoolDelegationRecord
- type UtxoSpendRef
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddStakeRef ¶
func AddStakeRef( refs map[string]CredentialSlotRef, ref models.StakeCredentialRef, slot uint64, )
AddStakeRef merges one (credential, slot) pair into refs, keeping the highest slot recorded for that credential. A ref with an empty key (no staking credential on the UTxO/output) is ignored.
func CreditLiveStakeDelta ¶
func CreditLiveStakeDelta( db *gorm.DB, ref models.StakeCredentialRef, amount uint64, slot uint64, ) (bool, error)
CreditLiveStakeDelta adds amount to an existing reward_live_stake row's reward_stake and total_stake in a single UPDATE, avoiding the full account SELECT + UTxO SUM + upsert that RefreshLiveStakeAggregate performs. This is safe only for a pure reward-stake credit: pool delegation, registered, and utxo_stake are left untouched, and the row's existing utxo_stake + (old reward_stake + amount) must still equal the new total_stake, which holds because total_stake is only ever set from a full refresh's utxoTotal+rewardStake sum.
reward_stake/total_stake are types.Uint64 columns stored as decimal-string TEXT (see types.Uint64.Value) on every backend, so the update casts to the backend's native integer type, adds, and casts back to a string type rather than relying on column affinity or implicit numeric-to-string conversion.
CreditLiveStakeDelta must run inside an active transaction. MySQL and Postgres take a SELECT ... FOR UPDATE row lock for the overflow check; SQLite drops that clause, but its single-writer transaction semantics provide the required serialization. All callers use a caller-supplied transaction or db.Transaction so the check and UPDATE remain one atomic operation.
Returns true if a row was updated; false (with no error) when no reward_live_stake row exists yet for this credential, in which case the caller must fall back to RefreshLiveStakeAggregate.
func CurrentTipSlot ¶
CurrentTipSlot returns the metadata tip slot using the caller's transaction. A fresh database has no tip row and therefore returns slot zero.
func DeleteStateAfterSlot ¶
DeleteStateAfterSlot deletes reward-state rows captured from rolled-back blocks. When txn is non-nil, db is used as-is; otherwise the deletes are wrapped in their own transaction.
func DeleteStateBeforeEpoch ¶
DeleteStateBeforeEpoch deletes reward-state rows older than the retained snapshot window. When txn is non-nil, db is used as-is; otherwise the deletes are wrapped in their own transaction.
func GetAdaPots ¶
GetAdaPots retrieves reward-related ADA pots for an epoch.
func GetPoolInputs ¶
GetPoolInputs retrieves all per-pool reward inputs for an epoch.
func GetSnapshot ¶
GetSnapshot retrieves reward snapshot metadata for an epoch.
func GroupRefsBySlot ¶
func GroupRefsBySlot( refs map[string]CredentialSlotRef, ) (map[uint64][]models.StakeCredentialRef, error)
GroupRefsBySlot validates every ref in refs and groups them by the slot at which their reward-live-stake aggregate should be recomputed, skipping refs with no stake credential key. Callers use the returned map to batch-fetch certificate state (batchFetchCerts) once per slot before calling RefreshLiveStakeAggregate for each ref.
func LiveStakeNeedsBackfill ¶
LiveStakeNeedsBackfill reports whether any canonical account or live-UTxO credential is missing from reward_live_stake. Testing for missing keys, not merely an empty aggregate, also repairs upgraded databases where post-upgrade writes populated only part of the table before the first restart.
func RebuildLiveStake ¶
RebuildLiveStake fully repopulates the reward_live_stake table from current account/UTxO/certificate state. Callers are responsible for transaction scoping (db is used as-is, with no internal transaction/savepoint).
utxoJoinHint is an optional backend-specific fragment inserted immediately after `LEFT JOIN utxo` (e.g. sqlite's `INDEXED BY <index>` query-planner hint); pass "" when the backend has no equivalent syntax.
The dialect casts below are dispatched once per call via integerCastType, transactionTableName, and boolLiteral: this is the single shared SQL that replaces three near-identical per-backend copies, one of which (mysql) had drifted to omit the CAST on account.reward for the reward_stake column that postgres already applied. Casting account.reward uniformly here removes that drift by construction.
func RefreshLiveStakeAggregate ¶
func RefreshLiveStakeAggregate( db *gorm.DB, ref models.StakeCredentialRef, slot uint64, poolDelegationCache PoolDelegationCache, ) error
RefreshLiveStakeAggregate recomputes and upserts the reward_live_stake row for a single stake credential from current account/UTxO state. This is the per-credential engine shared by RebuildLiveStake's full rebuild and every incremental refresh path (account changes, UTxO create/spend, rollback).
poolDelegationCache is the (optional) batch-fetched certificate state for this slot; nil (or a missing entry) falls back to the account row's own AddedSlot for the pool-delegation ordering, which is used for accounts imported without certificate history (e.g. genesis/Mithril bootstrap).
func SaveAdaPots ¶
func SaveAdaPots(db *gorm.DB, pots *models.RewardAdaPots) error
SaveAdaPots saves reward-related ADA pots for an epoch.
func SavePoolInputs ¶
func SavePoolInputs(db *gorm.DB, inputs []*models.RewardPoolInput) error
SavePoolInputs saves per-pool reward inputs for an epoch.
func SaveSnapshot ¶
func SaveSnapshot(db *gorm.DB, snapshot *models.RewardSnapshot) error
SaveSnapshot saves reward snapshot metadata for an epoch.
func StakeRefsFromLiveUtxoIDs ¶
func StakeRefsFromLiveUtxoIDs( db *gorm.DB, utxos []models.UtxoId, slot uint64, chunkSize int, ) (map[string]CredentialSlotRef, error)
StakeRefsFromLiveUtxoIDs is equivalent to StakeRefsFromUtxoIDs but ignores already-spent rows. Physical cleanup of spent UTxOs must not recompute live stake: the spend path already removed their value, and recomputing at a historical DeletedSlot can replace a newer delegation aggregate.
func StakeRefsFromUtxoIDs ¶
func StakeRefsFromUtxoIDs( db *gorm.DB, utxos []models.UtxoId, slot uint64, chunkSize int, ) (map[string]CredentialSlotRef, error)
StakeRefsFromUtxoIDs resolves a batch of UTxO identifiers (tx hash + output index) to their stake credentials and merges them into a fresh credential/slot map. When slot is 0, the ref's slot is derived per-row from the UTxO's own AddedSlot/DeletedSlot (used by rollback-driven refreshes, where each UTxO may need a different recompute slot). chunkSize bounds how many UTxOs are placed in a single SQL statement.
func StakeRefsFromUtxoSpends ¶
func StakeRefsFromUtxoSpends( db *gorm.DB, spends []UtxoSpendRef, chunkSize int, ) (map[string]CredentialSlotRef, error)
StakeRefsFromUtxoSpends resolves a batch of just-spent UTxOs to their stake credentials, keyed to the slot each spend was recorded at, and merges them into a fresh credential/slot map. chunkSize bounds how many spends are placed in a single SQL statement.
func ValidateLiveStakeRef ¶
func ValidateLiveStakeRef(ref models.StakeCredentialRef) error
ValidateLiveStakeRef reports whether ref is a well-formed stake credential for the reward_live_stake table: an empty key is allowed (nothing to touch), but a non-empty key must have a valid tag (0=key, 1=script) and be exactly 28 bytes.
func ValidateLiveStakeSourceCredentials ¶
ValidateLiveStakeSourceCredentials checks that every account and live-UTxO credential feeding the reward_live_stake rebuild is well-formed (tag 0 or 1, exactly 28 bytes), returning a descriptive error naming which source table and how many rows are invalid.
Types ¶
type CredentialSlotRef ¶
type CredentialSlotRef struct {
Ref models.StakeCredentialRef
Slot uint64
}
CredentialSlotRef pairs a stake credential with the slot at which its reward-live-stake aggregate should be recomputed. Each backend keeps its own local map type (keyed the same way, via models.StakeCredentialRef.MapKey) because callers outside the scope of this package (account.go, batch_accumulator.go, transaction.go, utxo.go) destructure the map value's fields directly; this type exists for the query helpers in this file that don't need the backend-local field names.
type PoolDelegationCache ¶
type PoolDelegationCache map[string]PoolDelegationRecord
PoolDelegationCache maps a stake credential's MapKey (see models.StakeCredentialRef.MapKey) to its most recent pool delegation certificate, as populated by each backend's batchFetchCerts. A nil cache (or a missing entry) means "no certificate history available"; callers fall back to the account row's own AddedSlot.
type PoolDelegationRecord ¶
type PoolDelegationRecord struct {
Pool []byte
AddedSlot uint64
BlockIndex uint64
CertIndex uint32
}
PoolDelegationRecord is the subset of a certificate record needed to order and apply a stake credential's most recent pool delegation. It mirrors each backend's local certRecord (defined in account.go) restricted to the fields RefreshLiveStakeAggregate needs.
type UtxoSpendRef ¶
UtxoSpendRef mirrors the subset of each backend's local utxoSpend row (defined in batch_accumulator.go) that StakeRefsFromUtxoSpends needs: the spent UTxO's identity and the slot the spend was recorded at.