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.
- Call
executeLocalStateQueryExpr with VolatileTip to query chain point, block number, system start, and era history.
- Convert to timestamp via the existing
slotToTimestamp.
- 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
Out of scope
FetchBlock, DumpHistory, FollowTip (separate issues).
- Extracting the shared tip-query helper is encouraged but not required.
Dependencies
References
Summary
Implement the
ReadTipRPC method from the UTxO RPCSyncServicespec, returning the current chain tip as aBlockRef(slot, hash, height, timestamp).Motivation
Simplest SyncService entry point
ReadTipis the simplest of the fourSyncServicemethods.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
QueryServicehandler to populate theirledger_tipfields.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.ReadTipprovides this over gRPC, removing the need for a direct N2C socket connection for the initial tip check.Background
What the spec requires
ReadTipRequestis empty (no parameters).ReadTipResponsereturns a singleBlockRefwith:slot(uint64)hash(bytes)height(uint64)timestamp(uint64, milliseconds)Existing infrastructure
The chain tip is already assembled in every
QueryServicehandler via:The conversion to proto is handled by
mkChainPointMsginType.hs, which produces aChainPointmessage with the same four fields asBlockRef(slot, hash, height, timestamp).No dependency on ADR-019
Unlike
FetchBlockandFollowTip,ReadTipdoes not need node kernel access.The existing N2C
LocalStateQuerypath is sufficient - it's the same query pattern already used byReadParams,ReadUtxos, andSearchUtxos.Proposed approach
Proto additions
The sync proto file (
proto/utxorpc/v1beta/sync/sync.proto) will be added as part of #1216 (FetchBlock).If
ReadTiplands first, add the proto file here and expose onlyReadTip;FetchBlockwill add its method to the same file.For this issue, declare only
rpc ReadTip(ReadTipRequest) returns (ReadTipResponse)in theSyncServiceblock.Handler
New function
readTipMethodin a newCardano/Rpc/Server/Internal/UtxoRpc/Sync.hsmodule.executeLocalStateQueryExprwithVolatileTipto query chain point, block number, system start, and era history.slotToTimestamp.BlockRefresponse (reuse or adaptmkChainPointMsg).The tip-query logic is currently duplicated across
readParamsMethod,readUtxosMethod, andsearchUtxosMethod.Consider extracting it into a shared helper as part of this work.
Server wiring
Register the new
SyncServicealongside the existingQueryServiceandSubmitServiceinrunRpcServer.Acceptance criteria
proto/utxorpc/v1beta/sync/sync.protoadded (or extended if gRPC: Implement FetchBlock (UTxO RPC SyncService) in cardano-rpc #1216 lands first),ReadTipRPC exposed.buf generate proto.readTipMethodhandler implemented using existing N2CLocalStateQuerypath.SyncServiceregistered inrunRpcServer.ReadTip, verify returned slot and hash match the testnet's current tip.cardano-rpc/README.mdupdated to markReadTipas supported in the coverage table.Out of scope
FetchBlock,DumpHistory,FollowTip(separate issues).Dependencies
References
utxorpc/specrepo,proto/utxorpc/v1beta/sync/sync.proto