Skip to content

DO NOT MERGE: Update to crypton == 1.1 and replace memory package with ram - #1292

Draft
erikd wants to merge 62 commits into
masterfrom
erikd/crypton+ram
Draft

DO NOT MERGE: Update to crypton == 1.1 and replace memory package with ram#1292
erikd wants to merge 62 commits into
masterfrom
erikd/crypton+ram

Conversation

@erikd

@erikd erikd commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Context

The package crypton < 1.1 depends on memory and >= 1.1 depends on ram. This does not affect consensus directly, but has a huge impact on the whole stack, ledger, consensus and node all need to be changed/fixed at once.

The commits in this PR will be used on an experiment branch of cardano-node to make sure everything works.

How to trust this PR

Highlight important bits of the PR that will make the review faster. If there are commands the reviewer can run to observe the new behavior, describe them.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. See Running tests for more details
  • Self-reviewed the diff
  • Changelog fragment added in .changes/

Copilot AI lite review requested due to automatic review settings August 13, 2026 06:42
@erikd
erikd requested a review from disassembler as a code owner August 13, 2026 06:42
@erikd
erikd marked this pull request as draft August 13, 2026 06:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the cardano-api/cardano-rpc stack to support the crypton >= 1.1 ecosystem shift (notably the memoryram dependency change) and adjusts crypto serialization code to use the newer fixed-size raw encoding APIs. It also adds temporary cabal.project pins/allow-newer to align a set of upstream packages for an experiment branch.

Changes:

  • Migrate DSIGN/KES/VRF/BLS raw key/signature (de)serialization to Cardano.Binary.FixedSizeCodec (rawEncodeFixedSized / rawDecodeFixedSized).
  • Bridge cardano-addresses’ vendored XPrv to cardano-crypto’s XPrv via the shared 96-byte compact format.
  • Update Cabal dependencies (bounds + ram replacement) and add temporary cabal.project pins/allow-newer for upstream compatibility during the migration.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Tx.hs Encode vkey witnesses using fixed-size raw encoding.
cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Type/Byron.hs Encode Byron bootstrap witness vkeys using fixed-size raw encoding.
cardano-rpc/cardano-rpc.cabal Bump crypto/binary deps and switch memoryram in lib + tests.
cardano-api/test/cardano-api-test/Test/Cardano/Api/Crypto.hs Update crypto serialization properties to fixed-size codec helpers.
cardano-api/src/Cardano/Api/Tx/Internal/Sign.hs Adapt witness decoding to newer validation API and use fixed-size sig decoding.
cardano-api/src/Cardano/Api/Key/Internal/Praos.hs Switch KES/VRF raw bytes serialization to fixed-size codec APIs.
cardano-api/src/Cardano/Api/Key/Internal/Mnemonic.hs Convert derived XPrv from cardano-addresses to cardano-crypto format via bytes.
cardano-api/src/Cardano/Api/Key/Internal/Leios.hs Switch BLS raw bytes serialization to fixed-size codec APIs; update PoP context constant usage.
cardano-api/src/Cardano/Api/Key/Internal.hs Switch many key roles’ raw bytes serialization to fixed-size codec APIs.
cardano-api/src/Cardano/Api/Crypto/Ed25519Bip32.hs Provide FixedSizeCodec instances and CBOR via encodeFixedSized/decodeFixedSized.
cardano-api/cardano-api.cabal Update dependency bounds, remove memory, add ram, bump validation.
cabal.project Add temporary allow-newer + source-repository-package pins for the migration.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cabal.project
Comment on lines +177 to +185
allow-newer:
cardano-ledger-mary:cardano-crypto-class,
cardano-ledger-shelley:cardano-crypto-class,
cardano-ledger-binary:cardano-crypto-class,
cardano-ledger-core:cardano-crypto-class,
cardano-protocol:cardano-crypto-class,
cardano-protocol-tpraos:cardano-crypto-class,
kes-agent:cardano-crypto-class,
kes-agent-crypto:cardano-crypto-class,
Comment thread cabal.project
Comment on lines +168 to +176
-- TEMPORARY: switching to crypton >= 1.1 (which depends on `ram` instead of
-- `memory`) needs cardano-crypto-class-2.6.0.0 (the first version depending
-- on crypton ^>=1.1 and `ram`), but the released ouroboros-consensus-3.0.1.0
-- pins `cardano-crypto-class ^>=2.3`, which excludes it. The blocks below
-- replicate the (draft, do-not-merge) upstream fix in
-- https://github.com/IntersectMBO/ouroboros-consensus/pull/2213, which widens
-- ouroboros-consensus's bound to also allow cardano-crypto-class-2.6.0.0 and
-- pulls in the handful of other packages that need to move in lockstep with
-- it. Remove all of this once these land upstream and a release picks them up.
@erikd
erikd force-pushed the erikd/crypton+ram branch 4 times, most recently from 7af974d to 59a3157 Compare August 26, 2026 05:47
@erikd
erikd force-pushed the erikd/crypton+ram branch from 59a3157 to f0a61f6 Compare September 1, 2026 23:11
palas and others added 16 commits September 9, 2026 18:52
- per-wallet certificate menu: register / register+delegate / delegate-only /
  unregister; key deposit and refund reflected in the balance
- live pool picker from Blockfrost /pools/extended, one page at a time
  (prev/next; no duplicates possible from shifting offsets)
- delegation uses Blockfrost's hex pool id, with a golden-tested pure-Elm
  bech32 fallback decoder
- signing attaches payment witnesses per input wallet and a stake witness
  (alsoSignWithStakeKey) per certificate wallet
- README: full feature list
- pin the pool's Blockfrost hex (and ticker) into the certificate at pick
  time instead of re-resolving it from the currently loaded picker page at
  estimate/sign time; drop the poolHex fallback path
- stamp GotPools with the network and page it answers and drop stale replies,
  matching the GotUtxos landing-guard idiom
- validate fully in Bech32.bech32ToHex (BIP-173 checksum, pool prefix,
  28-byte payload, no mixed case); fix the fetchPools docstring (pages
  replace, not append)
- show the pending menu choice while the pool picker is open and replace the
  wallet's certificate only on a confirmed pick, so cancelling rolls back and
  the DOM select stays in sync
- decode and show metadata.ticker in the pool picker; search matches it
- compute the pager's has-more flag at the fetch boundary; toast on retry
  without a project id; log pool fetches like other Blockfrost calls; use
  LogInfo for cert edits
- ports.js: build the boot error message from DOM nodes/textContent instead
  of innerHTML; fail loudly on an empty payment-key list instead of wedging
  the wasm instance
- docs: restore the Types/Ports module docstrings, pparams.js (not .json),
  certificate building in the Wasm module doc, the real stake-witness rule,
  and an honest certMenu comment
Mostly interpolation of the previous eras: every eon dictionary and
case eliminator gets its Dijkstra arm (the
Allegra/Mary/Babbage/Conway-onwards dictionaries return `id`), plus
the `IsAllegra/Mary/Alonzo/BabbageBasedEra` instances, `TestEquality`
on `CardanoEra`, the experimental `Era`'s `Eon` instance, the `ToJSON`
`DijkstraLedgerPredFailure` instance the `ShelleyBasedEra` bundle
needs, the Dijkstra arms in the `TxOut` conversions and tx-body lenses
that the relaxation below makes reachable, and a Dijkstra arm
mirroring Conway in `makeStakeAddressDelegationCertificate`.

Two real changes. First, the ledger gates Shelley-style certificates
to `AtMostEra "Conway"`, so the eon constraint bundles no longer
provide `ShelleyEraTxCert` or `TxCert ~ ConwayTxCert` (breaking); call
sites that need them now require them explicitly. Second, Dijkstra
replaced required signer hashes with guards, so
`reqSignerHashesTxBodyL` has no working Dijkstra arm (mirroring the
ledger's own gate) and `createTransactionBody` instead translates
`TxExtraKeyWitnesses` into appended key-hash guards.

Simple scripts stay unsupported in Dijkstra: they need the era's new
guard construct in `SimpleScript` first. That also keeps
`txOutParseJson` unsupported, since Dijkstra tx outs can carry
reference scripts of the new native-script type.

Co-Authored-By: Sebastian Nagel <sebastian.nagel@ncoding.at>
Co-Authored-By: kderme <k.dermenz@gmail.com>
Co-Authored-By: Konstantinos Lambrou-Latreille <konstantinos.lambrou@iohk.io>
Co-Authored-By: John Lotoski <john.lotoski@iohk.io>
Co-Authored-By: Mateusz Galazyn <mateusz.galazyn@iohk.io>
gitlab.haskell.org is the only non-GitHub host among our flake inputs,
and an outage breaks this workflow at `nix develop` time. Pre-fetch the
ghc-wasm-meta input before the first nix invocation; if
gitlab.haskell.org
does not respond, fetch a byte-identical mirror of the pinned tarball
from archive.org instead. The input's narHash from flake.lock is
enforced
on both sources, so the fallback cannot alter the build inputs; once the
content is in the local store, the later nix invocations resolve the
locked input without contacting gitlab.

Mirror: https://archive.org/details/ghc-wasm-meta-c662c34d608dc9d2ff599b007f2e3c46138efaab
If the input is re-pinned, upload the new GitLab archive tarball to an
archive.org item named ghc-wasm-meta-<rev> (keeping GitLab's file name)
to keep the fallback working; the step fails with instructions otherwise
Drop the four constraint comments, deprecate cardano-api's
reqSignerHashesTxBodyL in favour of the ledger's lens and getter (the
old-API construction site now uses the ledger lens per era), pattern
match explicitly instead of using a wildcard in createTransactionBody's
required-signers case, and fix the Enum (Some Era) roundtrip
(toEnum 1 = Some DijkstraEra) while keeping maxBound at Conway.
Every wrapper that just re-dresses a ledger lens is deprecated in
favour of the ledger's own, and createTransactionBody now uses the
ledger lenses directly. Cardano.Api.Ledger gains the re-exports the
migration needs: the era tx-body classes, the affected lenses,
valueTxOutL and coinTxOutL. Kept undeprecated: the validity-interval
compatibility lenses, adaAssetL and multiAssetL, which have no ledger
equivalent (and adaAssetL is still used by cardano-testnet).
After the lens migration, mScriptIntegrityHash's only type-fixing use
sits under alonzoEraOnwardsConstraints, and older GHCs refuse to unify
the outer type variable there (it is untouchable under the constraint
implication); GHC 9.12+ solves it anyway. Pin the type at the binder
instead.
Address the two comments from the approving review:

Spell out the pre-Conway eras in the experimental `Eon Era` instance
instead of a wildcard, like the canonical eon instances do. The
wildcard would have silently classified any future era as outside the
eon; with explicit arms the next era forces a decision here at compile
time.

File the ledger re-exports added by the lens deprecation under their
era demarcations in Cardano.Api.Ledger.Internal.Reexport: they were
all appended to the Babbage section. This adds the missing Mary
section; valueTxOutL and coinTxOutL are core EraTxOut lenses, so they
go under Core.
The deprecated lens now carries the ledger's AtMostEra "Conway"
constraint, so Dijkstra misuse is a compile error instead of a runtime
one — which also collapses the lens back to a single equation with no
error arm.
Add DijkstraEraBasedProtocolParametersUpdate with
IntroducedInDijkstraPParams (the reference-script size and cost
parameters new in Dijkstra), the fromLedgerPParamsUpdate conversion
back into it, a Semigroup instance for DijkstraPParams updates and
generators. The protocol version itself is not updatable in Dijkstra.

Co-Authored-By: Konstantinos Lambrou-Latreille <konstantinos.lambrou@iohk.io>
Route all Conway-onwards queries (constitution, governance state,
DRep/SPO state and stake distributions, committee state, vote
delegatees, proposals, ratification and future parameters, default
votes and DRep delegations) through
caseShelleyToBabbageOrConwayEraOnwards with obtainCommonConstraints,
so they work in Dijkstra as well.

Co-Authored-By: Mateusz Galazyn <mateusz.galazyn@iohk.io>
Co-Authored-By: Sebastian Nagel <sebastian.nagel@ncoding.at>
Co-Authored-By: John Lotoski <john.lotoski@iohk.io>
These queries now dispatch in Conway and later eras, but the pre-Conway
error arms still claimed "only available in the Conway era"; say
"only available from the Conway era onwards" instead, and align the
QueryFuturePParams message, which had its own variant of the wording.
The experimental makeUnsignedTx builds Dijkstra transaction bodies,
translating extra key witnesses into appended key-hash guards (the
era's replacement for required signer hashes); fee estimation,
auto-balancing and execution-unit substitution for proposals gain
Dijkstra support; BalanceIsNegative carries the era's UnsignedTx
instead of a hardcoded Conway one; and vote witness extraction handles
Dijkstra in both APIs.

Co-Authored-By: John Lotoski <john.lotoski@iohk.io>
Co-Authored-By: Mateusz Galazyn <mateusz.galazyn@iohk.io>
Co-Authored-By: kderme <k.dermenz@gmail.com>
Add the "Tx DijkstraEra" text envelope types, generalize the
compatible-transaction path over Conway-onwards, declare Plutus V1-V3
script support in Dijkstra (V3 is the era's ledger maximum for now),
reexport DijkstraTxCert, and teach the generators that Dijkstra drops
IsValid False by design; the now-redundant direct DijkstraTxCert
import in cardano-rpc goes away.

Co-Authored-By: kderme <k.dermenz@gmail.com>
Co-Authored-By: Mateusz Galazyn <mateusz.galazyn@iohk.io>
Co-Authored-By: Konstantinos Lambrou-Latreille <konstantinos.lambrou@iohk.io>
Flip maxBound to Dijkstra and extend the Enum instances and the
era-name parsers accordingly, un-hiding the era from era enumeration
and selection, in the old and the experimental API alike.

This also fixes a latent Enum roundtrip crash: fromEnum already mapped
the Dijkstra constructors of AnyCardanoEra and AnyShelleyBasedEra
to 7, but toEnum errored on that index.

Co-Authored-By: Konstantinos Lambrou-Latreille <konstantinos.lambrou@iohk.io>
carbolymer and others added 27 commits September 9, 2026 18:54
ReadData and ReadTx need a whole-chain index (datum by hash,
transaction by hash) that cardano-node does not maintain, so they
cannot be implemented without building an external chain indexer into
the node. Distinguish them from the methods that are merely not yet
implemented.
Replace the rpcSocketPath field of RpcConfigF with an RpcEndpoint sum
type: the server listens either on a unix domain socket (default,
rpc.sock next to the node socket) or on plaintext TCP (HTTP/2 without
TLS) when a listen port is configured. The TCP listen address defaults
to 127.0.0.1. Trace the resolved endpoint on server start.
Add an RpcEndpointTcpTls endpoint: when TLS certificate and private key
files are configured, the server listens with TLS on the configured
host and port. Grapesy's default of honouring the SSLKEYLOGFILE
environment variable is explicitly disabled so the node never silently
logs TLS session keys.
Build the gRPC server with mkGrpcServer and runServer instead of the
runServerWithHandlers convenience wrapper, so the HTTP/2 settings are
explicit at the call site. Halve the maximum concurrent streams per
connection to 64; all other settings keep grapesy defaults, including
the HTTP/2 flood-protection rate limits and flow-control windows.
Redact handler exceptions sent to clients: the response carries the
error message only, never call stacks or internal detail; full detail
is still traced server-side. Bound script evaluation requests by a
64 KiB pre-decode size cap, the protocol maximum transaction size and
a limit of 100 redeemers. Limit UTxO reads to 20000 keys and block
fetches to 500 references per request. Document the security posture
in the package README.
Two of the three call sites discarded the `ShelleyEraOnly` witness
entirely, so they are expressed directly with `inEonForShelleyBasedEra`
and an `AllegraEraOnwards` default.

`invalidHereAfterTxBodyL` needs the `ShelleyEraOnly` witness in the
Shelley branch to reach `ttlAsInvalidHereAfterTxBodyL`, which
`inEonForShelleyBasedEra` cannot supply, so it now matches on the
`ShelleyBasedEra` constructors directly.
It had no call sites left, and its own comment marked it for deletion
once `build-raw --byron-era` was deprecated in cardano-cli. Callers
needing the same split can use `inEonForEra` with `ShelleyBasedEra`,
which is what the `Cardano.Api.Network.IPC` haddock example now shows.
…wards

Sixteen of the nineteen call sites ignored one of the two witnesses, so
they are expressed with `inEonForShelleyBasedEra` and a default for the
eras outside the eon.

Unlike the case combinator, `inEonForShelleyBasedEra` hands the callback
a witness but no constraints, so `maybeFromLedgerTxUpdateProposal` now
calls `shelleyToBabbageEraConstraints` itself.

In `toConsensusQueryShelleyBased` the eleven Conway-onwards queries go
through a local `conwayOnwards` witness which matches on
`ShelleyBasedEra` exhaustively instead of using an eon, so adding or
retiring an era is a compile error at that match rather than a silent
fall through to the unsupported branch. The witness is
`ConwayEraOnwards` and the constraints come from
`conwayEraOnwardsConstraints`, so these queries no longer depend on the
experimental `Era`, whose constructors only cover the currently
supported eras.

`nextEpochEligibleLeadershipSlots` needs a visible type application
because neither branch mentions the witness.
The three remaining call sites are certificate generators whose
pre-Conway branch needs `ShelleyEraTxCert` and whose Conway branch needs
`ConwayEraTxCert`. `inEonForShelleyBasedEra` supplies a witness but no
constraints, and its default argument has no witness at all, so these
match on the `ShelleyBasedEra` constructors and obtain the constraints
from the witness in each branch.

That empties `Cardano.Api.Era.Internal.Case`, so the module goes too.
Stop exporting the NodeKernelAccess record's fields. The node kernel
state is reachable only through Cardano.Rpc.Server.NodeKernelAccess's
functions (nodeKernelSystemStart, securityParam, genesisConfig,
readEraHistory, readChainTipHeader), so that module is the single place
that reads the record directly. The record itself lives in the
unexposed Cardano.Rpc.Server.NodeKernelAccess.Internal.Type module (per
ADR-009), which only the environment wiring imports.
Serve era summaries from the node kernel's hard-fork history: era name,
start and end boundaries (Unix-epoch milliseconds, slot, epoch). The
current era's end is left unset (no well-defined ending yet) and per-era
protocol parameters are left unset (the node keeps no historical
parameters; use ReadParams instead).
The package `crypton < 1.1` depends on `memory` and `>= 1.1` depends on
`ram`. By dropping the dependency on `memory` and adding the dependency
on `ram` we are effectively changing to `crypton >= 1.1`.
This change required due to dependence on cardano-crypto-class which in
turn was required to support crypton >= 1.1.
validation had no version bound in cardano-api.cabal. Its 1.2.2 release
(uploaded between the two Hackage index-states this crypton migration
spans) is a complete rewrite to a lens/profunctor-optics based API, which
dropped Valid.toEither/Valid.liftError used by
Cardano.Api.Tx.Internal.Sign.decodeShelleyBasedWitness.

Capping validation to <1.2 to keep that old API is not an option: the
ouroboros-consensus changes pulled in by the cabal.project SRP had
already migrated Ouroboros.Consensus.Shelley.Ledger.Mempool to the new
validation >=1.2 API (view Data.Validation.either) themselves, and
validation is a single globally-resolved package across the whole build
plan, so pinning it down for cardano-api's sake breaks
ouroboros-consensus-cardano instead.

Rewrite decodeShelleyBasedWitness to use only the primitives that are
stable across both API generations (the Valid.Failure/Valid.Success
constructors and the Semigroup/Monoid instances), and pin
validation ^>=1.2 to reflect what the build already requires
transitively.
…hanges

cardano-crypto-class-2.5.0.0 removed BLS12381SignContext's constructors
from export in favour of the pre-built minSigPoPDST/minVerKeyPoPDST
values, which broke Leios.hs's provisional reconstruction of that
context (already flagged there with a TODO anticipating this exact
change). Use Crypto.minSigPoPDST directly now that it's available.

The same version bump renamed cardano-crypto-class:testlib's
prop_cbor_with -> prop_cbor_fixed_sized, prop_cbor_direct_vs_class ->
prop_cbor_fixed_sized_vs_class, and added _fixed_sized variants of
prop_raw_serialise/prop_size_serialise built on FixedSizeCodec directly.
Switch Test.Cardano.Api.Crypto to the new names/variants, following on
from "Update all DSIGN operations to FixedSizeCodec ops".
…ic.hs

cardano-addresses' master (pulled in by the cabal.project SRP, needed for
its own crypton >=1.1/ram migration) vendored its own copy of
Cardano.Crypto.Wallet to drop the cardano-crypto/memory dependency,
rather than re-exporting cardano-crypto's module as before. Its XPrv is
now a distinct type from the Crypto.HD.XPrv ("Cardano.Crypto.Wallet",
from the standalone cardano-crypto package) that SigningKey constructors
expect.

Bridge the two via the same 96-byte compact raw format both sides
already implement (Cardano.Address.Derivation.xprvToBytes round-tripped
through Cardano.Api.Crypto.Ed25519Bip32.xPrvFromBytes) rather than
changing what type SigningKey wraps, so the on-disk/wire key format is
unaffected.
@erikd
erikd force-pushed the erikd/crypton+ram branch 2 times, most recently from 4348055 to 3db5a03 Compare September 10, 2026 00:41
…eption

grapesy changed serverExceptionToClient's field type from SomeException
to ExactException (a newtype wrapper) between 1.1.1 and 1.2.0. This
repo's own pinned Hackage index-state (2026-08-02) predates that
release, so CI still resolves an older grapesy with the old signature;
a newer index-state (as used downstream by cardano-node) resolves
1.2.0 and this commit's serverExceptionToClient assignment fails to
typecheck. Unwrap via the ExactException pattern before using
fromException, as grapesy's own Server.Call/Context modules do
internally.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants