Summary
Implement the ReadGenesis RPC method from the UTxO RPC QueryService spec, returning genesis configuration for all eras (Byron, Shelley, Alonzo, Conway) as a parsed cardano.Genesis message plus the genesis hash and CAIP-2 chain identifier.
Motivation
Spec coverage
ReadGenesis is one of four unimplemented QueryService methods.
The proto request/response messages (ReadGenesisRequest, ReadGenesisResponse) already exist in proto/utxorpc/v1beta/query/query.proto, but the rpc ReadGenesis(...) declaration is missing from the service block.
Removing filesystem dependency for chain-following clients
Chain-following clients like Kupo need genesis parameters (network magic, system start, security parameter k, epoch length, slot length, active slots coefficient) to function.
Today Kupo reads these from the node's on-disk genesis JSON files, which couples it to filesystem access on the same host as the node.
Serving genesis config over gRPC removes that coupling and lets remote clients bootstrap without out-of-band config distribution.
Background
What the spec requires
ReadGenesisRequest takes an optional FieldMask.
ReadGenesisResponse returns:
genesis (bytes) - genesis hash for the chain
caip2 (string) - the CAIP-2 chain identifier for this network
cardano oneof - a parsed cardano.Genesis message
The cardano.Genesis message (defined in cardano.proto) has 42 fields spanning 4 eras:
- Byron (fields 1-9): AVVM distribution, block version data, protocol consts, boot stakeholders, heavy delegation, non-AVVM balances, VSS certs
- Shelley (fields 10-23): active slots coefficient, epoch length, genesis delegations, initial funds, KES parameters, max lovelace supply, network ID/magic, protocol params, security param, slot length, system start, update quorum
- Alonzo (fields 24-31): lovelace per UTxO word, execution prices, max execution units, max value size, collateral config, cost models
- Conway (fields 32-42): committee, constitution, governance parameters, DRep parameters, voting thresholds
Data source
queryLedgerConfig (via the DebugLedgerConfig consensus query) returns CardanoLedgerConfig StandardCrypto, which contains the full per-era genesis configurations.
This is already available over N2C LocalStateQuery - no new node-side work is needed.
The per-era genesis data can be extracted from the CardanoLedgerConfig via the existing HardForkLedgerConfig telescope, giving access to:
- Byron:
ByronPartialLedgerConfig containing Genesis.Config
- Shelley+: per-era
TransitionConfig with tcShelleyGenesisL for the ShelleyGenesis, plus era-specific genesis via the transition config lenses
CAIP-2 identifier
The Cardano CAIP-2 chain identifier format is defined in CIP-34.
The exact format string should be derived per that spec during implementation.
The network magic needed to construct it is available from the genesis config.
Proposed approach
Proto changes
Add rpc ReadGenesis(ReadGenesisRequest) returns (ReadGenesisResponse) to the QueryService service block in query.proto.
The request/response messages already exist; only the service declaration is missing.
Regenerate Haskell bindings via buf generate proto.
Handler
New function readGenesisMethod in Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs (or a new Genesis.hs module if it gets large).
- Call
queryLedgerConfig via executeLocalStateQueryExpr to obtain CardanoLedgerConfig.
- Extract per-era genesis configs from the
HardForkLedgerConfig telescope.
- Map each era's fields to the corresponding
cardano.Genesis proto fields.
- Populate the
genesis hash field (see open question below on which genesis hash to use).
- Derive CAIP-2 identifier from the genesis config per CIP-34.
- Return
ReadGenesisResponse with all three fields populated.
Conversion module
The 42-field mapping from Haskell ledger types to the proto Genesis message is the bulk of the work.
Consider a dedicated Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hs conversion module to keep the handler clean.
Server wiring
Register ReadGenesis alongside the existing ReadParams, ReadUtxos, and SearchUtxos handlers in runRpcServer.
Implementation notes
Byron-era fields
Several Byron genesis fields (AVVM distribution, boot stakeholders, heavy delegation, VSS certs) are large maps that exist in the genesis JSON but are not retained in memory by the running node.
If CardanoLedgerConfig does not expose these, document the omission and leave the proto fields empty.
The Shelley-and-later fields are the ones clients actually use.
FieldMask
ReadGenesisRequest includes a FieldMask.
As with ReadParams and SearchUtxos, this can be ignored in the initial implementation (return all fields unconditionally) and noted as a future optimisation.
Which genesis hash?
The genesis response field is "genesis hash for the chain".
Cardano has separate genesis hashes for Byron, Shelley, Alonzo, and Conway.
The Shelley genesis hash is the conventional chain identity used by chain-following clients, but this should be confirmed against other UTxO RPC implementations before committing.
Cacheability
Genesis config is immutable for the lifetime of a network.
The handler can cache the response after the first call rather than re-querying the node on every request.
This is an optimisation, not a requirement for the initial implementation.
Acceptance criteria
Out of scope
FieldMask support (ignore mask, return all fields).
- Response caching.
ReadEraSummary, ReadData, ReadTx (separate issues).
References
Summary
Implement the
ReadGenesisRPC method from the UTxO RPCQueryServicespec, returning genesis configuration for all eras (Byron, Shelley, Alonzo, Conway) as a parsedcardano.Genesismessage plus the genesis hash and CAIP-2 chain identifier.Motivation
Spec coverage
ReadGenesisis one of four unimplementedQueryServicemethods.The proto request/response messages (
ReadGenesisRequest,ReadGenesisResponse) already exist inproto/utxorpc/v1beta/query/query.proto, but therpc ReadGenesis(...)declaration is missing from the service block.Removing filesystem dependency for chain-following clients
Chain-following clients like Kupo need genesis parameters (network magic, system start, security parameter k, epoch length, slot length, active slots coefficient) to function.
Today Kupo reads these from the node's on-disk genesis JSON files, which couples it to filesystem access on the same host as the node.
Serving genesis config over gRPC removes that coupling and lets remote clients bootstrap without out-of-band config distribution.
Background
What the spec requires
ReadGenesisRequesttakes an optionalFieldMask.ReadGenesisResponsereturns:genesis(bytes) - genesis hash for the chaincaip2(string) - the CAIP-2 chain identifier for this networkcardanooneof - a parsedcardano.GenesismessageThe
cardano.Genesismessage (defined incardano.proto) has 42 fields spanning 4 eras:Data source
queryLedgerConfig(via theDebugLedgerConfigconsensus query) returnsCardanoLedgerConfig StandardCrypto, which contains the full per-era genesis configurations.This is already available over N2C LocalStateQuery - no new node-side work is needed.
The per-era genesis data can be extracted from the
CardanoLedgerConfigvia the existingHardForkLedgerConfigtelescope, giving access to:ByronPartialLedgerConfigcontainingGenesis.ConfigTransitionConfigwithtcShelleyGenesisLfor theShelleyGenesis, plus era-specific genesis via the transition config lensesCAIP-2 identifier
The Cardano CAIP-2 chain identifier format is defined in CIP-34.
The exact format string should be derived per that spec during implementation.
The network magic needed to construct it is available from the genesis config.
Proposed approach
Proto changes
Add
rpc ReadGenesis(ReadGenesisRequest) returns (ReadGenesisResponse)to theQueryServiceservice block inquery.proto.The request/response messages already exist; only the service declaration is missing.
Regenerate Haskell bindings via
buf generate proto.Handler
New function
readGenesisMethodinCardano/Rpc/Server/Internal/UtxoRpc/Query.hs(or a newGenesis.hsmodule if it gets large).queryLedgerConfigviaexecuteLocalStateQueryExprto obtainCardanoLedgerConfig.HardForkLedgerConfigtelescope.cardano.Genesisproto fields.genesishash field (see open question below on which genesis hash to use).ReadGenesisResponsewith all three fields populated.Conversion module
The 42-field mapping from Haskell ledger types to the proto
Genesismessage is the bulk of the work.Consider a dedicated
Cardano/Rpc/Server/Internal/UtxoRpc/Type/Genesis.hsconversion module to keep the handler clean.Server wiring
Register
ReadGenesisalongside the existingReadParams,ReadUtxos, andSearchUtxoshandlers inrunRpcServer.Implementation notes
Byron-era fields
Several Byron genesis fields (AVVM distribution, boot stakeholders, heavy delegation, VSS certs) are large maps that exist in the genesis JSON but are not retained in memory by the running node.
If
CardanoLedgerConfigdoes not expose these, document the omission and leave the proto fields empty.The Shelley-and-later fields are the ones clients actually use.
FieldMask
ReadGenesisRequestincludes aFieldMask.As with
ReadParamsandSearchUtxos, this can be ignored in the initial implementation (return all fields unconditionally) and noted as a future optimisation.Which genesis hash?
The
genesisresponse field is "genesis hash for the chain".Cardano has separate genesis hashes for Byron, Shelley, Alonzo, and Conway.
The Shelley genesis hash is the conventional chain identity used by chain-following clients, but this should be confirmed against other UTxO RPC implementations before committing.
Cacheability
Genesis config is immutable for the lifetime of a network.
The handler can cache the response after the first call rather than re-querying the node on every request.
This is an optimisation, not a requirement for the initial implementation.
Acceptance criteria
rpc ReadGenesis(ReadGenesisRequest) returns (ReadGenesisResponse)declared inquery.protoservice block.buf generate proto.readGenesisMethodhandler implemented, extracting genesis config viaqueryLedgerConfig.cardano.Genesisproto fields populated where the data is available fromCardanoLedgerConfig. Byron fields that are not retained in memory documented as absent.genesis(hash) andcaip2(chain ID) response fields populated.runRpcServer.ReadGenesis, verify network magic and system start match the testnet's known values.cardano-rpc/README.mdupdated to markReadGenesisas supported in the coverage table.Out of scope
FieldMasksupport (ignore mask, return all fields).ReadEraSummary,ReadData,ReadTx(separate issues).References
utxorpc/specrepo,proto/utxorpc/v1beta/query/query.proto