| License | Apache-2.0 |
|---|---|
| Safe Haskell | None |
| Language | GHC2021 |
Singular.Registry.Driver
Description
A fold's speculative session starts from the manager's COMMITTED trie and
is discarded (updateTokenWithDuties). So a caller that lands a fold and
does not mirror the edge into its manager builds the next proof against a
root the chain no longer has. The library stays correct throughout; the
caller is silently wrong, and the failure surfaces at the NEXT fold, which
looks like a defect somewhere else entirely. That cost three devnet runs
and an escalation on #173.
The obligation lived in a comment, so each new caller could forget it. This module is where it lives now.
A caller cannot reach a fold except through a Registry, and the only way
to obtain one is bootRegistry. foldEdge books the edge, builds the
fold, submits it, mirrors it, and proves on both sides that the manager
and the chain agree:
- BEFORE building, the manager's root must equal the chain's. A caller that landed a fold behind this driver's back is rejected HERE, naming both roots, rather than at some later unrelated fold.
- AFTER mirroring, the two must agree again, and the root must have moved. A root that does not move across a landed fold is the #173 defect, and it would otherwise be invisible.
What this module does NOT do is assert anything about the edge's meaning. Booting, folding and keeping the mirror in step are its whole subject; every caller keeps its own assertions and its own output.
Synopsis
- data Registry
- registryConfig :: Registry -> CageConfig
- registryTokenId :: Registry -> TokenId
- registryRefs :: Registry -> [(TxIn, TxOut ConwayEra)]
- registryBootTx :: Registry -> ConwayTx
- bootRegistry :: CageConfig -> NamingCodes -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> TrieManager IO -> IO Registry
- foldEdge :: Registry -> ByteString -> Edge -> IO FoldOutcome
- foldEdgeTo :: Registry -> ByteString -> Edge -> (ByteString, Maybe Data) -> IO FoldOutcome
- data FoldOutcome = FoldOutcome {
- foKey :: ByteString
- foEdge :: Edge
- foBooking :: TxIn
- foFoldTx :: ConwayTx
- foRootBefore :: Root
- foRootAfter :: Root
- chainRoot :: Registry -> IO OnChainRoot
- mirrorRoot :: Registry -> IO Root
- renderRoot :: ByteString -> String
- tokenIdOfBootTx :: CageConfig -> ConwayTx -> IO TokenId
The registry handle
A booted registry, with everything a fold of its edges needs. The
constructor is deliberately NOT exported: bootRegistry is the only way
to obtain one, so there is no state in which a caller holds the means to
fold and has not been through the boot that publishes the references and
creates the trie.
registryConfig :: Registry -> CageConfig Source #
The configuration this registry was booted against.
registryTokenId :: Registry -> TokenId Source #
The token the boot minted.
registryRefs :: Registry -> [(TxIn, TxOut ConwayEra)] Source #
The published reference outputs every fold resolves its scripts through. A caller that books an edge itself needs them.
registryBootTx :: Registry -> ConwayTx Source #
The signed boot transaction, for a caller that reports on it.
Booting
Arguments
| :: CageConfig | |
| -> NamingCodes | |
| -> (Network, LedgerProvider NoWitness IO) | |
| -> SubmitSigned | |
| -> Addr | The payer, which is also where boot outputs land |
| -> TrieManager IO | |
| -> IO Registry |
Boot a registry: mint its token, create its trie, and publish the cage references every later fold resolves through.
The state validator alone is fifteen kilobytes against a sixteen-kilobyte
transaction cap, so the references are published once here rather than
attached per fold (publishCageRefs). The boot itself resolves
the state validator through a publication already in the payer's
wallet, and is refused StateValidatorNotPublished without one.
Folding one edge
foldEdge :: Registry -> ByteString -> Edge -> IO FoldOutcome Source #
Book one edge, fold it, and commit it into the manager before any later proof is built.
The order is not the caller's to get wrong, and the two root checks are not the caller's to remember. See the module header for why both exist.
Arguments
| :: Registry | |
| -> ByteString | |
| -> Edge | |
| -> (ByteString, Maybe Data) | destination address and the datum it carries, as |
| -> IO FoldOutcome |
Fold one edge whose delivery goes to an explicitly named destination rather than the one the edge would route to by itself.
The naming application routes an insertActive to its own script
address; a harness that has no spending arm there names a wallet
instead. That is the only difference, so it is a parameter here rather
than a second driver.
data FoldOutcome Source #
What one landed fold did, as the caller's receipt. The two roots are the evidence that the mirror moved with the chain rather than behind it.
Constructors
| FoldOutcome | |
Fields
| |
Reading the two roots
chainRoot :: Registry -> IO OnChainRoot Source #
The root the chain holds, read off the state UTxO at the cage address.
mirrorRoot :: Registry -> IO Root Source #
The committed root the manager holds for this registry.
renderRoot :: ByteString -> String Source #
A root as the driver's diagnostics render it: lowercase hex, no quoting. A caller that wants to assert on a rejection's text builds the same string from a root it read itself, so the assertion binds the values rather than the phrasing.
Deriving the token a boot minted
tokenIdOfBootTx :: CageConfig -> ConwayTx -> IO TokenId Source #
The token a boot transaction minted, read off its own mint field. Six harnesses each carried a copy of this; it belongs here.