88-- (fetching blocks, dumping history, following the tip).
99module Cardano.Rpc.Server.Internal.UtxoRpc.Sync
1010 ( fetchBlockMethod
11+ , readTipMethod
1112 )
1213where
1314
1415import Cardano.Api
16+ import Cardano.Api.Consensus qualified as Consensus
1517import Cardano.Rpc.Proto.Api.UtxoRpc.Sync qualified as U5c
1618import Cardano.Rpc.Server.Internal.Error
1719import Cardano.Rpc.Server.Internal.Monad
@@ -23,6 +25,7 @@ import Cardano.Rpc.Server.NodeKernelAccess
2325import RIO
2426
2527import Data.ByteString qualified as BS
28+ import Data.ByteString.Short qualified as SBS
2629import Data.ProtoLens (defMessage )
2730import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds )
2831import Network.GRPC.Spec (GrpcError (GrpcInternal , GrpcInvalidArgument , GrpcNotFound ), Proto )
@@ -88,3 +91,35 @@ fetchBlockMethod request = do
8891 & U5c. cardano . U5c. body . U5c. tx .~ txs
8992 & U5c. cardano . U5c. timestamp .~ timestampMs
9093 )
94+
95+ -- | Handle the @ReadTip@ SyncService RPC method.
96+ -- Reads the current chain tip from ChainDB and returns it as slot, block
97+ -- header hash, block height and slot timestamp.
98+ -- When the chain is at origin, the tip field is left unset.
99+ readTipMethod
100+ :: MonadRpc e m
101+ => Proto U5c. ReadTipRequest
102+ -> m (Proto U5c. ReadTipResponse )
103+ readTipMethod _request = do
104+ NodeKernelAccess {chainDb, systemStart, readEraHistory} <- grabNodeKernelAccess
105+ tipHeader <- liftIO $ Consensus. getTipHeader chainDb
106+ tip <- forM tipHeader $ \ header -> do
107+ let slot = Consensus. blockSlot header
108+ Consensus. OneEraHash tipHash = Consensus. blockHash header
109+ BlockNo height = Consensus. blockNo header
110+ throwPastHorizon =
111+ throwGrpcErrorWithMessage GrpcInternal $
112+ " cannot convert tip slot "
113+ <> tshow (unSlotNo slot)
114+ <> " to timestamp: the slot is past the era history horizon"
115+ eraHistory <- readEraHistory
116+ timestampMs <-
117+ slotToUTCTime systemStart eraHistory slot
118+ & either (const throwPastHorizon) (pure . round . (* 1000 ) . utcTimeToPOSIXSeconds)
119+ pure $
120+ defMessage
121+ & U5c. slot .~ unSlotNo slot
122+ & U5c. hash .~ SBS. fromShort tipHash
123+ & U5c. height .~ height
124+ & U5c. timestamp .~ timestampMs
125+ pure $ defMessage & U5c. maybe'tip .~ tip
0 commit comments