cardano-rpc
Safe HaskellNone
LanguageHaskell2010

Cardano.Rpc.Server.Internal.UtxoRpc.Sync

Description

Handlers for the UTxO RPC SyncService - synchronising chain data (fetching blocks, dumping history, following the tip).

Synopsis

Documentation

fetchBlockMethod Source #

Arguments

:: MonadRpc e m 
=> Proto FetchBlockRequest

Request containing a block reference (slot + hash)

-> m (Proto FetchBlockResponse)

Response containing the fetched block with raw CBOR and cardano header

Handle the FetchBlock SyncService RPC method. Fetches a block from ChainDB by slot and header hash. Byron-era transactions carry no fee: Byron fees are implicit (inputs minus outputs) and computing them needs UTxO lookups this handler does not do. Returns NOT_FOUND if the requested block is missing. Returns INVALID_ARGUMENT if the block reference has an invalid hash.

followTipMethod Source #

Arguments

:: MonadRpc e m 
=> Proto FollowTipRequest

Request containing optional intersection points (slot + hash)

-> (NextElem (Proto FollowTipResponse) -> IO ())

Callback used to send each streamed response

-> m () 

Handle the FollowTip SyncService RPC method: stream fully parsed blocks as the chain advances.

Where the stream starts: at the first of the request's intersection points found on the chain, in client preference order. A block ref with an empty hash means origin. An empty intersect list means the current tip.

What the client receives: first a reset announcing the start point, then an apply per adopted block. A rollback becomes undo actions carrying the rolled-back blocks, re-fetched from ChainDB and streamed newest first. When the blocks can no longer be re-fetched, because garbage collection won the race against the client, the rollback becomes a reset carrying the rollback point's BlockRef instead, slot and hash only, like ChainSync's MsgRollBackward. The tracked window is sized to the node's security parameter k, so no rollback consensus can produce falls outside it (see NodeKernelAccess). Every response also carries the current chain tip.

Errors: INVALID_ARGUMENT if an intersection block ref has an invalid hash, NOT_FOUND if none of the intersection points are on the chain.

Runs until the client disconnects or the stream is otherwise closed; withFollower closes the follower on every exit path.

followTipStream Source #

Arguments

:: (HasCallStack, MonadIO m) 
=> ChainFollower

Follower to stream changes from

-> m (Maybe (Proto BlockRef))

Read the current chain tip, projected into a BlockRef

-> (SlotNo -> m UTCTime)

Convert a slot to its wall-clock timestamp

-> (ChainPoint -> m (Maybe (ByteString, BlockInMode)))

Re-fetch a block by point, to reconstruct undo payloads on rollback. Nothing means the block is no longer available (e.g. the VolatileDB has garbage-collected it past the immutable tip); the loop falls back to reset in that case.

-> Int

How many applied points to track for undo re-fetch. In production this is the node's security parameter k (securityParam). Consensus never rolls back more than k blocks, so tracking k points covers every rollback the protocol can produce, on any network. An entry costs roughly 40 bytes, so the window costs about 40 * k bytes per stream: around 86 KB on mainnet, where k = 2160. A rollback deeper than the cap degrades to reset.

-> (NextElem (Proto FollowTipResponse) -> IO ())

Callback used to send each streamed response

-> [ChainPoint]

Resolved, non-empty intersection points, in client preference order

-> m () 

The FollowTip streaming loop. Finds the intersection with the given points, then streams chain changes as they arrive.

The collaborators are plain arguments rather than a NodeKernelAccess so tests can drive the loop with a scripted follower and stubbed capabilities, no live ChainDB required (see Test.Cardano.Rpc.FollowTipStream, the first unit coverage of this loop). MonadIO is enough for all of them, including the gRPC error path (throwGrpcErrorWithMessage).

How a rollback is delivered, by case:

  1. The target is within the tracked window, meaning it is one of the last trackingCap applied points or the window floor (the stream's start point, on which a rollback undoes everything tracked). Each rolled-back block is re-fetched by point and emitted as undo, newest first.
  2. A re-fetch misses mid-undo because garbage collection won the race: a single reset at the rollback target. Partial undo followed by reset is coherent because reset is absolute positioning.
  3. The target is outside the window, either deeper than the cap or the initial rollback-to-intersection when nothing is tracked yet: a single reset, as in 2.

Every emitted message, apply or undo or reset, carries the current tip.

Throws NOT_FOUND if none of the intersection points are on the chain. Runs until the client disconnects or the stream is otherwise closed; follower cleanup is the caller's responsibility (see withFollower).

readTipMethod :: MonadRpc e m => Proto ReadTipRequest -> m (Proto ReadTipResponse) Source #

Handle the ReadTip SyncService RPC method. Reads the current chain tip from ChainDB and returns it as slot, block header hash, block height and slot timestamp. When the chain is at origin, the tip field is left unset.