Documentation
¶
Overview ¶
Package conformance provides a DingoStateManager that implements the ouroboros-mock conformance.StateManager interface using dingo's ledger state models.
Index ¶
- Variables
- type DingoStateManager
- func (m *DingoStateManager) ApplyTransaction(tx common.Transaction, slot uint64) error
- func (m *DingoStateManager) Close() error
- func (m *DingoStateManager) GetGovernanceState() *conformance.GovernanceState
- func (m *DingoStateManager) GetProtocolParameters() common.ProtocolParameters
- func (m *DingoStateManager) GetStateProvider() conformance.StateProvider
- func (m *DingoStateManager) GetStateSnapshot() *conformance.StateSnapshot
- func (m *DingoStateManager) LoadInitialState(state *conformance.ParsedInitialState, pp common.ProtocolParameters) error
- func (m *DingoStateManager) ProcessEpochBoundary(newEpoch uint64) error
- func (m *DingoStateManager) Reset() error
- func (m *DingoStateManager) SetRewardAccountBalances(balances map[mockledger.RewardAccountKey]uint64)
- func (m *DingoStateManager) SetRewardBalances(balances map[common.Blake2b224]uint64)
- type DingoStateProvider
- func (p *DingoStateProvider) CalculateRewards(pots common.AdaPots, snapshot common.RewardSnapshot, ...) (*common.RewardCalculationResult, error)
- func (p *DingoStateProvider) CommitteeCredentialMember(coldCredential common.Credential) (*common.CommitteeMember, error)
- func (p *DingoStateProvider) CommitteeHotCredentialMember(hotCredential common.Credential) (*common.CommitteeMember, error)
- func (p *DingoStateProvider) CommitteeMember(coldKey common.Blake2b224) (*common.CommitteeMember, error)
- func (p *DingoStateProvider) CommitteeMembers() ([]common.CommitteeMember, error)
- func (p *DingoStateProvider) CommitteeStateAvailable() (bool, error)
- func (p *DingoStateProvider) Constitution() (*common.Constitution, error)
- func (p *DingoStateProvider) CostModels() map[common.PlutusLanguage]common.CostModel
- func (p *DingoStateProvider) DRepDelegation(cred common.Credential) (*common.Drep, error)
- func (p *DingoStateProvider) DRepRegistration(credential common.Credential) (*common.DRepRegistration, error)
- func (p *DingoStateProvider) DRepRegistrations() ([]common.DRepRegistration, error)
- func (p *DingoStateProvider) GetAdaPots() common.AdaPots
- func (p *DingoStateProvider) GetRewardSnapshot(epoch uint64) (common.RewardSnapshot, error)
- func (p *DingoStateProvider) GovActionById(id common.GovActionId) (*common.GovActionState, error)
- func (p *DingoStateProvider) GovActionExists(id common.GovActionId) bool
- func (p *DingoStateProvider) IsPoolRegistered(poolKeyHash common.PoolKeyHash) bool
- func (p *DingoStateProvider) IsRewardAccountRegistered(cred common.Credential) bool
- func (p *DingoStateProvider) IsStakeCredentialRegistered(cred common.Credential) bool
- func (p *DingoStateProvider) IsVrfKeyInUse(vrfKeyHash common.Blake2b256) (bool, common.PoolKeyHash, error)
- func (p *DingoStateProvider) NetworkId() uint
- func (p *DingoStateProvider) PoolCurrentState(poolKeyHash common.PoolKeyHash) (*common.PoolRegistrationCertificate, *uint64, error)
- func (p *DingoStateProvider) RewardAccountBalance(cred common.Credential) (*uint64, error)
- func (p *DingoStateProvider) SlotToTime(slot uint64) (time.Time, error)
- func (p *DingoStateProvider) StakeCredentialDeposit(cred common.Credential) (*uint64, error)
- func (p *DingoStateProvider) StakeRegistration(stakingKey []byte) ([]common.StakeRegistrationCertificate, error)
- func (p *DingoStateProvider) TimeToSlot(t time.Time) (uint64, error)
- func (p *DingoStateProvider) TreasuryValue() (uint64, error)
- func (p *DingoStateProvider) UpdateAdaPots(pots common.AdaPots) error
- func (p *DingoStateProvider) UtxoById(id common.TransactionInput) (common.Utxo, error)
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("conformance: not found")
ErrNotFound is returned when a requested item is not found
Functions ¶
This section is empty.
Types ¶
type DingoStateManager ¶
type DingoStateManager struct {
// contains filtered or unexported fields
}
DingoStateManager implements conformance.StateManager against a real Dingo database.Database (sqlite/postgres/mysql metadata store plus a local Badger blob store), composed the same way the production node composes its storage plugins at startup. UTxOs, certificates, and governance state are all read from and written to this real backend -- see ApplyTransaction, ProcessEpochBoundary, and state_provider.go -- reusing dingo's own production persistence code (database.SetTransactionMetadataOnly, ledger/governance) rather than hand-rolling a second implementation against the raw metadata.MetadataStore interface.
govState mirrors the subset of state (proposal votes/thresholds, pending-committee bookkeeping) the upstream conformance harness reads via GetGovernanceState to pre-validate the *next* event before this manager applies it; it is kept from drifting out of step with the real backend by being driven from the exact same certificate/proposal/vote processing calls that also write to the real database (see updateGovStateForCertificate, recordProposalsInGovState, recordVotesInGovState), and epoch-boundary ratification/enactment decisions are persisted back to the real database via governance.EnactProposal / Database.SetGovernanceProposal rather than mutating only this in-memory mirror.
func NewDingoStateManager ¶
func NewDingoStateManager() (*DingoStateManager, error)
NewDingoStateManager creates a DingoStateManager backed by a real, local SQLite metadata store (plus a local Badger blob store), composed through the same plugin.Resolve path the production node uses at startup.
func (*DingoStateManager) ApplyTransaction ¶
func (m *DingoStateManager) ApplyTransaction( tx common.Transaction, slot uint64, ) error
ApplyTransaction implements conformance.StateManager.ApplyTransaction.
func (*DingoStateManager) Close ¶
func (m *DingoStateManager) Close() error
Close releases state-manager resources: the database, its provider host, and -- for a manager-owned data directory (the plain NewDingoStateManager constructor) -- the directory itself. It never drops a remote schema or database: NewDingoPostgresStateManager/NewDingoMysqlStateManager share one schema/database across every call in their process (see postgresProcessSchema's doc comment in state_manager_postgres.go and mysqlProcessDatabase's in state_manager_mysql.go), so an individual manager's Close must not drop a resource a sibling manager elsewhere in the same process may still be using -- that cleanup belongs to TestMain (conformance_main_test.go), once, after every test in the process has finished.
func (*DingoStateManager) GetGovernanceState ¶
func (m *DingoStateManager) GetGovernanceState() *conformance.GovernanceState
GetGovernanceState implements conformance.StateManager.GetGovernanceState.
func (*DingoStateManager) GetProtocolParameters ¶
func (m *DingoStateManager) GetProtocolParameters() common.ProtocolParameters
GetProtocolParameters implements conformance.StateManager.GetProtocolParameters.
func (*DingoStateManager) GetStateProvider ¶
func (m *DingoStateManager) GetStateProvider() conformance.StateProvider
GetStateProvider implements conformance.StateManager.GetStateProvider.
func (*DingoStateManager) GetStateSnapshot ¶ added in v0.70.13
func (m *DingoStateManager) GetStateSnapshot() *conformance.StateSnapshot
GetStateSnapshot implements conformance.StateSnapshotProvider. The conformance harness compares only observable ledger state; the database remains authoritative for validation while this projection tracks the committed UTxO identities alongside the same writes.
func (*DingoStateManager) LoadInitialState ¶
func (m *DingoStateManager) LoadInitialState( state *conformance.ParsedInitialState, pp common.ProtocolParameters, ) error
LoadInitialState implements conformance.StateManager.LoadInitialState.
func (*DingoStateManager) ProcessEpochBoundary ¶
func (m *DingoStateManager) ProcessEpochBoundary(newEpoch uint64) error
ProcessEpochBoundary implements conformance.StateManager.ProcessEpochBoundary.
Pool retirement has no separate real-database write here: a pool's PoolRetirementCertificate is already persisted (pool + pool_retirement rows) at certificate-application time via SetTransactionMetadataOnly in ApplyTransaction, and DingoStateProvider.PoolCurrentState/IsPoolRegistered determine registered-vs-retired status by comparing that stored retirement epoch against the current epoch at read time -- so there is nothing further to persist at the boundary itself.
Ratification/enactment decisions are made by the same vector-validated heuristic the harness has always used (see ratifyProposals/enactProposal below), not by invoking the full governance.ProcessEpoch orchestration: ProcessEpoch's real ratification path performs stake-weighted DRep/SPO/committee tallying against the database's live stake distribution, which synthetic per-vector seed data isn't guaranteed to model with the fidelity that requires, and a mismatch there would show up as vector regressions, not as an isolated persistence gap. Enactment side effects that a ratified proposal must apply (committee membership, protocol parameters, constitution, treasury withdrawal) are instead persisted by calling the real governance.EnactProposal directly against the already-persisted governance_proposal row once this manager's own heuristic decides to enact it -- reusing dingo's production side-effect code without re-deriving its ratification math. governance.ProcessEpoch is exercised directly, end-to-end, by TestProcessEpochAgainstRealBackend in state_manager_backend_test.go.
func (*DingoStateManager) Reset ¶
func (m *DingoStateManager) Reset() error
Reset implements conformance.StateManager.Reset. It clears the pre-validation govState mirror and empties the real backend so the next vector starts from a genuinely clean database, not just clean bookkeeping.
func (*DingoStateManager) SetRewardAccountBalances ¶ added in v0.70.2
func (m *DingoStateManager) SetRewardAccountBalances( balances map[mockledger.RewardAccountKey]uint64, )
SetRewardAccountBalances implements conformance.RewardAccountBalanceSetter. It updates registered accounts by full credential identity without creating or removing registrations. See SetRewardBalances's doc comment for why this stays in the govState mirror.
func (*DingoStateManager) SetRewardBalances ¶
func (m *DingoStateManager) SetRewardBalances( balances map[common.Blake2b224]uint64, )
SetRewardBalances implements conformance.StateManager.SetRewardBalances.
Reward-account balances are injected by the harness itself (precomputed from the vector's final_state plus future withdrawals -- see ouroboros-mock/conformance's adjustRewardBalances), not derived from anything Dingo's ApplyTransaction commits from decoded block data the way UTxOs/certificates/governance rows are. There is also no real backend primitive for an absolute reward-balance set (only Database.Add*AccountRewardByCredential, which credits a delta and can't express a decrease). Real reward calculation (ledger/chainsync.go's applyStakeRewards) is explicitly out of scope for this harness. Balances therefore stay in the govState mirror, matching how the upstream harness already treats them as synthetic validation input rather than application state.
type DingoStateProvider ¶
type DingoStateProvider struct {
// contains filtered or unexported fields
}
DingoStateProvider implements conformance.StateProvider by wrapping DingoStateManager to satisfy all gouroboros state interfaces. Every read method below queries manager.db -- the real, configured backend -- live; none of them read from any in-memory mirror of UTxO/certificate/pool/ DRep/committee state (see state_manager.go's type doc comment for the one narrow, documented exception: reward-account balances, which are harness-injected synthetic validation input, not application state Dingo itself commits).
func NewDingoStateProvider ¶
func NewDingoStateProvider(manager *DingoStateManager) *DingoStateProvider
NewDingoStateProvider creates a new DingoStateProvider.
func (*DingoStateProvider) CalculateRewards ¶
func (p *DingoStateProvider) CalculateRewards( pots common.AdaPots, snapshot common.RewardSnapshot, params common.RewardParameters, ) (*common.RewardCalculationResult, error)
CalculateRewards calculates rewards for the given epoch
func (*DingoStateProvider) CommitteeCredentialMember ¶ added in v0.70.5
func (p *DingoStateProvider) CommitteeCredentialMember( coldCredential common.Credential, ) (*common.CommitteeMember, error)
func (*DingoStateProvider) CommitteeHotCredentialMember ¶ added in v0.70.5
func (p *DingoStateProvider) CommitteeHotCredentialMember( hotCredential common.Credential, ) (*common.CommitteeMember, error)
func (*DingoStateProvider) CommitteeMember ¶
func (p *DingoStateProvider) CommitteeMember( coldKey common.Blake2b224, ) (*common.CommitteeMember, error)
CommitteeMember looks up a constitutional committee member by credential hash. Enacted (real, committed) members -- including the vector's initial committee, loaded into the backend by LoadInitialState -- are read from the backend directly and never fall back to the govState mirror: govState.CommitteeMembers holds that same initial/enacted set (see LoadFromParsedState and enactProposal), so falling back to it here would let a backend that drops or cannot read a committee_member row still report the vector as passing. A member proposed by a pending (not yet enacted) UpdateCommittee action is the one case with no real committee_member row to read yet, so that case resolves the persisted proposal directly.
func (*DingoStateProvider) CommitteeMembers ¶
func (p *DingoStateProvider) CommitteeMembers() ([]common.CommitteeMember, error)
CommitteeMembers returns every enacted committee member -- including the vector's initial committee, loaded into the backend by LoadInitialState -- read from the backend directly. It never merges in govState.CommitteeMembers: that map holds the same initial/enacted set (see LoadFromParsedState and enactProposal), so merging it here would let a backend that drops or cannot read a committee_member row still report the vector as passing. Unlike CommitteeMember, there is no per-credential caller asking about a specific pending UpdateCommittee proposal here, so there is no commit-free case left to fall back for.
func (*DingoStateProvider) CommitteeStateAvailable ¶ added in v0.70.5
func (p *DingoStateProvider) CommitteeStateAvailable() (bool, error)
CommitteeStateAvailable reports that the harness can answer committee queries authoritatively whenever its backend is reachable.
This deliberately differs from LedgerView.CommitteeStateAvailable, which derives authority from the seated member set. The two providers have different knowledge. A conformance vector declares its complete initial committee, and seedGovernanceState writes exactly that set, so zero rows here means the vector declared an empty committee -- authoritatively empty, which must still reject a non-member's certificate. Deriving availability from row count would instead report unavailable and decline to reject, failing any vector that expects NotCommitteeMemberError against an empty committee.
Production instead derives authority from the include-deleted member set, which distinguishes a committee emptied by NoConfidence (soft-deleted rows, authoritative) from one never populated (no rows, ambiguous because Dingo never persists the Conway genesis committee, blinklabs-io/dingo#3785). The harness needs no such inference: it has no genesis-sync path, so reachable already implies complete. Once #3785 lands the two answers converge.
func (*DingoStateProvider) Constitution ¶
func (p *DingoStateProvider) Constitution() (*common.Constitution, error)
Constitution returns the enacted constitution -- anchor URL, anchor hash, and optional guardrails policy hash -- read from the real backend, in the same shape production's ledger.LedgerView.Constitution reports.
It never falls back to the govState mirror: that mirror is seeded from the same vector state LoadInitialState writes to the backend, so falling back to it would let a backend that drops or cannot read a constitution row still report the vector as passing. Missing or malformed constitution state fails closed through governance.ConstitutionFromModel, and a failed read is returned as the wrapped store error.
func (*DingoStateProvider) CostModels ¶
func (p *DingoStateProvider) CostModels() map[common.PlutusLanguage]common.CostModel
CostModels returns which Plutus language versions have cost models defined. CostModel values are empty markers (struct{} upstream).
func (*DingoStateProvider) DRepDelegation ¶ added in v0.67.0
func (p *DingoStateProvider) DRepDelegation( cred common.Credential, ) (*common.Drep, error)
DRepDelegation returns the DRep a stake credential is vote-delegated to, or nil if it is not delegated. Used to validate reward withdrawals on protocol versions 10 and 11. Reads the account's real account.drep column through the real backend, matching production's ledger.LedgerView.DRepDelegation, rather than the govState pre-validation mirror: a real backend that never persists or returns account.drep correctly would still pass every vector here if this read the mirror instead, since ApplyTransaction's certificate processing writes delegation through the real SetTransactionMetadataOnly path regardless of what this read side consults.
func (*DingoStateProvider) DRepRegistration ¶
func (p *DingoStateProvider) DRepRegistration( credential common.Credential, ) (*common.DRepRegistration, error)
DRepRegistration looks up a DRep registration by its full credential.
func (*DingoStateProvider) DRepRegistrations ¶
func (p *DingoStateProvider) DRepRegistrations() ([]common.DRepRegistration, error)
DRepRegistrations returns all DRep registrations
func (*DingoStateProvider) GetAdaPots ¶
func (p *DingoStateProvider) GetAdaPots() common.AdaPots
GetAdaPots returns the current ADA pots
func (*DingoStateProvider) GetRewardSnapshot ¶
func (p *DingoStateProvider) GetRewardSnapshot( epoch uint64, ) (common.RewardSnapshot, error)
GetRewardSnapshot returns the stake snapshot for reward calculation
func (*DingoStateProvider) GovActionById ¶
func (p *DingoStateProvider) GovActionById( id common.GovActionId, ) (*common.GovActionState, error)
GovActionById looks up a governance action by its ID against the real backend.
func (*DingoStateProvider) GovActionExists ¶
func (p *DingoStateProvider) GovActionExists(id common.GovActionId) bool
GovActionExists checks if a governance action exists
func (*DingoStateProvider) IsPoolRegistered ¶
func (p *DingoStateProvider) IsPoolRegistered( poolKeyHash common.PoolKeyHash, ) bool
IsPoolRegistered checks if a pool is currently active -- see poolIsActive.
func (*DingoStateProvider) IsRewardAccountRegistered ¶
func (p *DingoStateProvider) IsRewardAccountRegistered( cred common.Credential, ) bool
IsRewardAccountRegistered checks if a reward account is registered
func (*DingoStateProvider) IsStakeCredentialRegistered ¶
func (p *DingoStateProvider) IsStakeCredentialRegistered( cred common.Credential, ) bool
IsStakeCredentialRegistered checks if a stake credential is currently registered
func (*DingoStateProvider) IsVrfKeyInUse ¶
func (p *DingoStateProvider) IsVrfKeyInUse( vrfKeyHash common.Blake2b256, ) (bool, common.PoolKeyHash, error)
IsVrfKeyInUse checks if a VRF key hash is registered by another pool. Conformance tests don't currently test VRF key uniqueness.
func (*DingoStateProvider) NetworkId ¶
func (p *DingoStateProvider) NetworkId() uint
NetworkId returns the network identifier
func (*DingoStateProvider) PoolCurrentState ¶
func (p *DingoStateProvider) PoolCurrentState( poolKeyHash common.PoolKeyHash, ) (*common.PoolRegistrationCertificate, *uint64, error)
PoolCurrentState returns the current state of a pool. A pool's PoolRetirementCertificate is already persisted (pool + pool_retirement rows) at certificate-application time via SetTransactionMetadataOnly in ApplyTransaction, so there is nothing further to read at epoch-boundary time -- see ProcessEpochBoundary's doc comment. The pending retirement epoch, when any, is derived by pendingPoolRetirementEpoch (matching ledger.LedgerView.PoolCurrentState); whether the pool is still considered actively registered is decided by poolIsActive -- see its doc comment.
func (*DingoStateProvider) RewardAccountBalance ¶
func (p *DingoStateProvider) RewardAccountBalance( cred common.Credential, ) (*uint64, error)
RewardAccountBalance returns the current reward balance for a stake credential. Reward balances are harness-injected synthetic validation input (see DingoStateManager.SetRewardBalances's doc comment), so this reads the govState mirror rather than the real backend.
func (*DingoStateProvider) SlotToTime ¶
func (p *DingoStateProvider) SlotToTime(slot uint64) (time.Time, error)
SlotToTime converts a slot number to a time
func (*DingoStateProvider) StakeCredentialDeposit ¶ added in v0.70.7
func (p *DingoStateProvider) StakeCredentialDeposit( cred common.Credential, ) (*uint64, error)
StakeCredentialDeposit returns the deposit recorded when the stake credential registered, or nil when the credential is not registered or the recorded deposit is unknown.
Without this method the harness does not satisfy common.StakeCredentialDepositState, so UtxoValidateValueNotConservedUtxo's optional type assertion misses and every legacy stake deregistration in the corpus is refunded at the current KeyDeposit. The corpus then cannot distinguish a correct recorded refund from the fallback, which is the gap #3831 covers.
This mirrors ledger.LedgerView.StakeCredentialDeposit: the account lookup gates on the same live registration state as IsStakeCredentialRegistered above, the registration history carries the deposit actually paid, and the import baseline stands in for a credential established by a vector's initial state rather than by a certificate in that vector. A nil return is preserved rather than coerced to zero, because the rule treats any non-nil value as authoritative.
func (*DingoStateProvider) StakeRegistration ¶
func (p *DingoStateProvider) StakeRegistration( stakingKey []byte, ) ([]common.StakeRegistrationCertificate, error)
StakeRegistration looks up stake registrations by staking key
func (*DingoStateProvider) TimeToSlot ¶
func (p *DingoStateProvider) TimeToSlot(t time.Time) (uint64, error)
TimeToSlot converts a time to a slot number
func (*DingoStateProvider) TreasuryValue ¶
func (p *DingoStateProvider) TreasuryValue() (uint64, error)
TreasuryValue returns the treasury value from the real backend, in the same shape production's ledger.LedgerView.TreasuryValue reports.
It never answers a synthetic zero. The harness does not seed treasury/pot accounting (see DingoStateManager.persistEnactment), so an unseeded backend has no network-state row at all. Returning 0 for that would make a provider that cannot answer look healthy: the upstream current-treasury-value rule only queries this method once a transaction body actually carries key 21, and it compares for equality, so a synthetic zero silently rejects every vector that declares a non-zero value and silently accepts one declaring zero. Failing closed reports the missing harness state instead.
func (*DingoStateProvider) UpdateAdaPots ¶
func (p *DingoStateProvider) UpdateAdaPots(pots common.AdaPots) error
UpdateAdaPots updates the ADA pots
func (*DingoStateProvider) UtxoById ¶
func (p *DingoStateProvider) UtxoById( id common.TransactionInput, ) (common.Utxo, error)
UtxoById looks up a UTxO by transaction input, reading through the real backend (metadata row plus blob-stored output CBOR -- see DingoStateManager.createUtxo).