Skip to content

gRPC: Implement ReadTip (UTxO RPC SyncService) in cardano-rpc #1218

@carbolymer

Description

@carbolymer

Summary

Implement the ReadTip RPC method from the UTxO RPC SyncService spec, returning the current chain tip as a BlockRef (slot, hash, height, timestamp).

Motivation

Simplest SyncService entry point

ReadTip is the simplest of the four SyncService methods.
It is a unary call with no parameters that returns a single BlockRef.
The data it needs (chain point, block number, system start, era history) is already queried by every existing QueryService handler to populate their ledger_tip fields.

Enabling remote chain-following clients

Chain-following clients like Kupo use a one-shot tip query at startup (via ChainSync MsgRequestNext) to learn the current chain position before beginning synchronisation.
ReadTip provides this over gRPC, removing the need for a direct N2C socket connection for the initial tip check.

Background

What the spec requires

ReadTipRequest is empty (no parameters).

ReadTipResponse returns a single BlockRef with:

  • slot (uint64)
  • hash (bytes)
  • height (uint64)
  • timestamp (uint64, milliseconds)

Existing infrastructure

The chain tip is already assembled in every QueryService handler via:

chainPoint  <- queryChainPoint
blockNo     <- queryChainBlockNo
systemStart <- querySystemStart
eraHistory  <- queryEraHistory
timestamp   <- slotToTimestamp systemStart eraHistory chainPoint

The conversion to proto is handled by mkChainPointMsg in Type.hs, which produces a ChainPoint message with the same four fields as BlockRef (slot, hash, height, timestamp).

No dependency on ADR-019

Unlike FetchBlock and FollowTip, ReadTip does not need node kernel access.
The existing N2C LocalStateQuery path is sufficient - it's the same query pattern already used by ReadParams, ReadUtxos, and SearchUtxos.

Proposed approach

Proto additions

The sync proto file (proto/utxorpc/v1beta/sync/sync.proto) will be added as part of #1216 (FetchBlock).
If ReadTip lands first, add the proto file here and expose only ReadTip; FetchBlock will add its method to the same file.

For this issue, declare only rpc ReadTip(ReadTipRequest) returns (ReadTipResponse) in the SyncService block.

Handler

New function readTipMethod in a new Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs module.

  1. Call executeLocalStateQueryExpr with VolatileTip to query chain point, block number, system start, and era history.
  2. Convert to timestamp via the existing slotToTimestamp.
  3. Build the BlockRef response (reuse or adapt mkChainPointMsg).

The tip-query logic is currently duplicated across readParamsMethod, readUtxosMethod, and searchUtxosMethod.
Consider extracting it into a shared helper as part of this work.

Server wiring

Register the new SyncService alongside the existing QueryService and SubmitService in runRpcServer.

Acceptance criteria

  • proto/utxorpc/v1beta/sync/sync.proto added (or extended if gRPC: Implement FetchBlock (UTxO RPC SyncService) in cardano-rpc #1216 lands first), ReadTip RPC exposed.
  • Generated Haskell bindings regenerated via buf generate proto.
  • readTipMethod handler implemented using existing N2C LocalStateQuery path.
  • SyncService registered in runRpcServer.
  • Integration test in cardano-testnet: call ReadTip, verify returned slot and hash match the testnet's current tip.
  • cardano-rpc/README.md updated to mark ReadTip as supported in the coverage table.

Out of scope

  • FetchBlock, DumpHistory, FollowTip (separate issues).
  • Extracting the shared tip-query helper is encouraged but not required.

Dependencies

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

Status
Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions