| License | Apache-2.0 |
|---|---|
| Safe Haskell | None |
| Language | GHC2021 |
Singular.Registry.TxBuilder.Edges
Description
M1 admits insertActive and updateTerminal (#157 seven-admitted-edges), and every processed edge rides on an approval the naming application's mint arm certified (#157 tree-edge-admission-by-approval, approval-asset-binding). A caller that wants a fold to land therefore needs three things this module supplies: the four policy pins derived from the naming partition's own compiled code, a booking transaction that carries each edge's certification — which edges get an approval, what it is, and nothing at all for a read — and the duties context the fold discharges its obligations from.
The state validator alone is fifteen kilobytes, so a fold that attaches
it, the request validator and a token policy does not fit in a
transaction. publishCageRefs publishes them once as reference outputs
and every purpose resolves through those instead.
Every consumer of the application — the conformance rows, the devnet end-to-end and the bounded journey — derives its pins and books its edges the same way, so all three move together.
Synopsis
- type SubmitSigned = ConwayTx -> IO ConwayTx
- registryIdOf :: CageConfig -> ByteString
- witnessScriptOf :: CageConfig -> NamingCodes -> Integer -> Script ConwayEra
- namingPins :: NamingCodes -> ByteString -> (ShortByteString, ShortByteString, ShortByteString, ShortByteString)
- publishRefScript :: (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> Script ConwayEra -> IO (TxIn, TxOut ConwayEra)
- publishRefScriptReserving :: Set TxIn -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> Script ConwayEra -> IO (TxIn, TxOut ConwayEra)
- publishRefScriptTx :: Set TxIn -> Session NoWitness IO -> Addr -> Script ConwayEra -> IO (ConwayTx, TxOut ConwayEra)
- data PublicationFundingError
- = PublicationShortfall {
- pfeNeeded :: Integer
- pfeHeld :: Integer
- pfeLargest :: Integer
- | PublicationOversize { }
- = PublicationShortfall {
- selectPublicationInputs :: PParams ConwayEra -> Addr -> Script ConwayEra -> [(k, TxOut ConwayEra)] -> Either PublicationFundingError ([(k, TxOut ConwayEra)], TxOut ConwayEra, Integer)
- firstPublicationChange :: PParams ConwayEra -> Addr -> Script ConwayEra -> [(TxIn, TxOut ConwayEra)] -> Either PublicationFundingError (TxIn, ConwayTx, TxOut ConwayEra, [(TxIn, TxOut ConwayEra)], Integer)
- publicationFee :: Integer
- publicationMinChange :: Integer
- publicationRefCoin :: PParams ConwayEra -> Addr -> Script ConwayEra -> Integer
- publishStateRef :: CageConfig -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> IO (TxIn, TxOut ConwayEra)
- publishStateRefReserving :: Set TxIn -> CageConfig -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> IO (TxIn, TxOut ConwayEra)
- stateRefIn :: CageConfig -> [(TxIn, TxOut ConwayEra)] -> Maybe (TxIn, TxOut ConwayEra)
- publishCageRefs :: CageConfig -> NamingCodes -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> TokenId -> IO [(TxIn, TxOut ConwayEra)]
- adaOnlyOut :: TxOut ConwayEra -> Bool
- selectFunding :: Maybe TxIn -> [(TxIn, TxOut ConwayEra)] -> Either String (TxIn, TxOut ConwayEra)
- data BookingApproval = BookingApproval {
- baAsset :: MultiAsset
- baRedeemer :: Data
- baScript :: Script ConwayEra
- baScriptReference :: Maybe TxIn
- baReferenceInputs :: Set TxIn
- bookingApproval :: NamingCodes -> Edge -> ByteString -> ByteString -> (ByteString, ByteString) -> Maybe BookingApproval
- certifyBooking :: PParams ConwayEra -> TxIn -> Maybe BookingApproval -> ConwayTx -> ConwayTx
- bookEdge :: CageConfig -> NamingCodes -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> TokenId -> ByteString -> Edge -> IO TxIn
- bookEdgeTo :: CageConfig -> NamingCodes -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> TokenId -> ByteString -> Edge -> (ByteString, Maybe Data) -> IO TxIn
- bookEdgeWith :: CageConfig -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> TokenId -> ByteString -> Edge -> (ByteString, Maybe Data) -> Integer -> Maybe BookingApproval -> IO ConwayTx
- bookEdgeTx :: CageConfig -> Session NoWitness IO -> Addr -> TokenId -> ByteString -> Edge -> (ByteString, Maybe Data) -> Integer -> Maybe BookingApproval -> IO ConwayTx
- bookEdgeMeasured :: CageConfig -> Session NoWitness IO -> Addr -> TokenId -> ByteString -> Edge -> (ByteString, Maybe Data) -> Integer -> BookingApproval -> [(TxIn, TxOut ConwayEra)] -> Maybe TxIn -> IO ConwayTx
- edgeDeposit :: Integer
- edgeDestinationOf :: CageConfig -> NamingCodes -> Addr -> Edge -> (ByteString, Maybe Data)
- edgeRecordDatum :: Data
- registryContextFor :: CageConfig -> NamingCodes -> Session NoWitness IO -> [(TxIn, TxOut ConwayEra)] -> IO RegistryContext
Submission
type SubmitSigned = ConwayTx -> IO ConwayTx Source #
Sign a built transaction with the payer's key, submit it, and wait for it. The caller owns its own signing key and its own confirmation discipline, so it supplies this rather than the module guessing either.
Derived identity
registryIdOf :: CageConfig -> ByteString Source #
The registry id a witness policy is parameterized by: the state policy plus the token name this cage's seed determined.
witnessScriptOf :: CageConfig -> NamingCodes -> Integer -> Script ConwayEra Source #
The witness policy script of one token kind.
Arguments
| :: NamingCodes | |
| -> ByteString | The registry id: state script hash then boot token name |
| -> (ShortByteString, ShortByteString, ShortByteString, ShortByteString) | Application, absent, active, terminal |
The four pins a registry identity carries (#157 genesis-policy-pins), derived
from the naming partition's own compiled code: the application validator
for the approval, and witness(kind, registry) at kinds 0, 1 and 2.
The registry id the witness policies are parameterized by depends on the state script hash and the boot seed, so this takes them directly rather than a configuration that does not exist yet.
Reference outputs
publishRefScript :: (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> Script ConwayEra -> IO (TxIn, TxOut ConwayEra) Source #
Publish one script as a reference output at the payer's own address.
publishRefScriptReserving :: Set TxIn -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> Script ConwayEra -> IO (TxIn, TxOut ConwayEra) Source #
publishRefScript, never spending a reserved output (#299): a caller
that has chosen the seed of a later boot keeps it unspent while it
publishes. The largest ada-only output that is not reserved funds it.
publishRefScriptTx :: Set TxIn -> Session NoWitness IO -> Addr -> Script ConwayEra -> IO (ConwayTx, TxOut ConwayEra) Source #
The unsigned publication of one reference script, funded by the shortest largest-first prefix of the ada-only outputs outside the reservation, and the reference output it creates.
data PublicationFundingError Source #
Why one publication cannot be funded: too little in total, or a covering prefix too large for the protocol maximum transaction size.
Constructors
| PublicationShortfall | |
Fields
| |
| PublicationOversize | |
Instances
| Show PublicationFundingError Source # | |
Defined in Singular.Registry.TxBuilder.Edges Methods showsPrec :: Int -> PublicationFundingError -> ShowS Source # show :: PublicationFundingError -> String Source # showList :: [PublicationFundingError] -> ShowS Source # | |
| Eq PublicationFundingError Source # | |
Defined in Singular.Registry.TxBuilder.Edges Methods (==) :: PublicationFundingError -> PublicationFundingError -> Bool Source # (/=) :: PublicationFundingError -> PublicationFundingError -> Bool Source # | |
selectPublicationInputs :: PParams ConwayEra -> Addr -> Script ConwayEra -> [(k, TxOut ConwayEra)] -> Either PublicationFundingError ([(k, TxOut ConwayEra)], TxOut ConwayEra, Integer) Source #
One owner of the publication arithmetic (#406): the shortest largest-first prefix of the permitted outputs whose total covers the reference output plus the fee plus a change strictly above the minimum, with the inputs, the reference output and the change; or the shortfall it names (needed total, held total, largest output). A covering prefix whose transaction would exceed the protocol maximum size is refused up front, naming size and limit, so a wallet of many dust outputs never reaches submission.
The permitted outputs are ada-only with no reference script, the seed withheld before the boot. A covering output spends exactly one input and it is the largest; otherwise no output that is not needed is spent.
firstPublicationChange :: PParams ConwayEra -> Addr -> Script ConwayEra -> [(TxIn, TxOut ConwayEra)] -> Either PublicationFundingError (TxIn, ConwayTx, TxOut ConwayEra, [(TxIn, TxOut ConwayEra)], Integer) Source #
The change output a first publication makes from the whole wallet, and
the seed it becomes (#406 slice 2): the shortest largest-first prefix of
all the ada-only outputs (nothing withheld) funds the state publication,
its change at index 1 is the chained seed. The body is exactly the one
publishRefScriptTx builds from the same view (flat fee, no validity
interval), so the transaction id — and the token it derives — is the same
in preview and in create. The arithmetic is selectPublicationInputs's;
this accessor adds only the body and its id.
publicationFee :: Integer Source #
The flat fee a publication pays, and the change it must leave strictly above. One owner (#406): the builder and the whole-run judgement share these with the pure selection below, never a second copy.
publicationMinChange :: Integer Source #
publicationRefCoin :: PParams ConwayEra -> Addr -> Script ConwayEra -> Integer Source #
The reference output a publication creates at the payer's address: the ledger minimum for the script plus one million lovelace. One owner: both the selection and the whole-run need share it.
publishStateRef :: CageConfig -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> IO (TxIn, TxOut ConwayEra) Source #
Publish the state validator as a reference output, once, before any boot (#177).
A registry boots only by reference: the boot resolves the state
validator through a publication in the payer's wallet and is refused
StateValidatorNotPublished without one, because that validator is
fifteen kilobytes against a sixteen-kilobyte transaction cap. A session
calls this before its first boot.
Idempotent by discovery: a wallet that already holds the publication gets it back rather than a second one, so a harness that boots several cages publishes once.
publishStateRefReserving :: Set TxIn -> CageConfig -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> IO (TxIn, TxOut ConwayEra) Source #
publishStateRef, never spending a reserved output (#299): an
existing publication is returned as before, and a new one is funded
outside the reservation.
stateRefIn :: CageConfig -> [(TxIn, TxOut ConwayEra)] -> Maybe (TxIn, TxOut ConwayEra) Source #
An output among these that publishes this cage's state validator.
publishCageRefs :: CageConfig -> NamingCodes -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> TokenId -> IO [(TxIn, TxOut ConwayEra)] Source #
Publish this cage's scripts as reference outputs: the cage, the request validator and the three token policies.
adaOnlyOut :: TxOut ConwayEra -> Bool Source #
Can this output fund a transaction? It must hold ada and nothing else, because it doubles as collateral, and it must not be one of the published reference outputs, because a transaction may not both spend an output and reference it.
selectFunding :: Maybe TxIn -> [(TxIn, TxOut ConwayEra)] -> Either String (TxIn, TxOut ConwayEra) Source #
The wallet output a transaction is funded and collateralised from: the one the caller chose, which must be an ada-only output of the wallet, or else the largest ada-only output. A caller that chose none still gets the output least likely to leave the change under its minimum.
Booking one edge
data BookingApproval Source #
What a tree-edge booking carries so the naming application
certifies it (DM-1): the asset it mints, the Approve redeemer the
mint arm reads, and the application script that witnesses the mint.
The asset name hashes the same (edge, key, owner, destination) the
redeemer carries, so one value binds both (DM-1-BIND).
Constructors
| BookingApproval | |
Fields
| |
Arguments
| :: NamingCodes | |
| -> Edge | Admissible edge, 0..6 |
| -> ByteString | Registry key |
| -> ByteString | Booker's key hash bytes |
| -> (ByteString, ByteString) | Destination: address bytes, datum hash |
| -> Maybe BookingApproval |
The booking certification decision, in one place (#240): which
edges carry an approval and what it is. A tree edge (0–5) carries the
approval approvalName binds; edgeWitnessTerminal carries none,
because open.ak refuses to certify a read and the cage never looks
for one — a booking that minted anyway is a transaction the node can
only reject. Admissibility of edge stays the caller's check.
Arguments
| :: PParams ConwayEra | Protocol parameters, for the script-integrity hash |
| -> TxIn | Ada-only input, collateral when an approval is present |
| -> Maybe BookingApproval | |
| -> ConwayTx | The booking with inputs, outputs, fee and signers set |
| -> ConwayTx |
Put a booking's certification into the transaction (DM-1b): with an approval, the mint, its redeemer, the script witness, the collateral and the script-integrity hash; without one, the booking unchanged — no redeemers, no witness, no collateral, and so no script-integrity hash, which the ledger computes for any transaction that could run a script.
bookEdge :: CageConfig -> NamingCodes -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> TokenId -> ByteString -> Edge -> IO TxIn Source #
Book an edge, routing its minted token to the destination
edgeDestinationOf chooses for it.
bookEdgeTo :: CageConfig -> NamingCodes -> (Network, LedgerProvider NoWitness IO) -> SubmitSigned -> Addr -> TokenId -> ByteString -> Edge -> (ByteString, Maybe Data) -> IO TxIn Source #
Book an edge, naming the destination explicitly (#173 I4, I5).
edgeDestinationOf sends an insertActive to the APPLICATION's own
script address, because the naming application is what creates the
record the active token witnesses. The OPEN registry has no such
application: `open.ak` is a minting policy with no spending arm at all,
so a token routed there would be locked forever.
The open story therefore names a WALLET, and the request carries that choice. Nothing on chain changes: the cage already checks the destination the request declares, and this is the off-chain builder learning to say something it could not say before.
Which edges carry an approval, what it is, and how the transaction
carries it is decided once, in bookingApproval and certifyBooking:
a tree edge mints and certifies, and a read books nothing at all.
Arguments
| :: CageConfig | |
| -> (Network, LedgerProvider NoWitness IO) | |
| -> SubmitSigned | |
| -> Addr | |
| -> TokenId | |
| -> ByteString | |
| -> Edge | |
| -> (ByteString, Maybe Data) | |
| -> Integer | The deposit, over and above the tip |
| -> Maybe BookingApproval | |
| -> IO ConwayTx |
Book an edge with the certification and deposit the caller's application decides (#299): the approval it mints, with any outputs it reads by reference, and the deposit the request rides with over the tip. The booker's own key is the request's owner and its required signer. Returns the signed booking as the submission callback handed it back; the request is its first output.
Arguments
| :: CageConfig | |
| -> Session NoWitness IO | |
| -> Addr | |
| -> TokenId | |
| -> ByteString | |
| -> Edge | |
| -> (ByteString, Maybe Data) | |
| -> Integer | The deposit, over and above the tip |
| -> Maybe BookingApproval | |
| -> IO ConwayTx |
The unsigned booking of one edge, built from one view: the payer's largest ada-only output pays the bond, the fee and the change.
Arguments
| :: CageConfig | |
| -> Session NoWitness IO | The one acquired view the booking is built, measured and certified from: its protocol parameters are the ones the caller reports and judges its outlay under, and nothing is submitted while it is held |
| -> Addr | |
| -> TokenId | |
| -> ByteString | |
| -> Edge | |
| -> (ByteString, Maybe Data) | |
| -> Integer | The deposit, over and above the tip |
| -> BookingApproval | |
| -> [(TxIn, TxOut ConwayEra)] | The resolved outputs the booking reads its scripts from |
| -> Maybe TxIn | The wallet output the caller chose to fund and collateralise |
| -> IO ConwayTx |
bookEdgeWith with its fee, units and collateral measured rather
than declared (#300).
The node's evaluator measures the booking's one purpose, the redeemer declares exactly those units, and the balancer charges the ledger's fee for the final body, reference scripts included — the resolved outputs the booking reads its script from are handed to it. The funding output, the wallet's largest ada-only output unless the caller chose one, is the collateral input, and the transaction states its total collateral at the protocol's percentage of the fee, rounded up, and a return carrying the rest of the output back. Everything is read from the one view the caller holds, and the booking is returned unsigned: the caller submits it after the view is released, and a caller that only prepares submits nothing.
edgeDeposit :: Integer Source #
The deposit a booking rides with, over and above the tip. The fold returns it to the destination the request named, or locks it in the custody an absence creates — it is never the folder's.
edgeDestinationOf :: CageConfig -> NamingCodes -> Addr -> Edge -> (ByteString, Maybe Data) Source #
Where an edge delivers (#157 request-destination-binding). An absence names the address its deposit comes back to and no datum; an activation names the naming application's own address and carries the record datum the delivered output will hold.
edgeRecordDatum :: Data Source #
The record datum a booking's destination carries. The cage checks only that the receiving output carries the datum the request carries — naming's own validators do not run at fold time — so one datum is enough.
Folding
registryContextFor :: CageConfig -> NamingCodes -> Session NoWitness IO -> [(TxIn, TxOut ConwayEra)] -> IO RegistryContext Source #
What a fold of tree edges needs in hand: the three token policies this registry pins, the cage script custody spends run, the cage's own UTxOs, the one destination datum a booking binds, and the reference outputs the fold's scripts resolve through.