Skip to content

cardano-rpc: Add timestamp to fetchBlock#1242

Open
carbolymer wants to merge 1 commit into
masterfrom
mgalazyn/feature/rpc-fetchblock-add-timestamp
Open

cardano-rpc: Add timestamp to fetchBlock#1242
carbolymer wants to merge 1 commit into
masterfrom
mgalazyn/feature/rpc-fetchblock-add-timestamp

Conversation

@carbolymer

Copy link
Copy Markdown
Contributor

Context

Additional context for the PR goes here. If the PR fixes a particular issue please provide a link to the issue.

How to trust this PR

Highlight important bits of the PR that will make the review faster. If there are commands the reviewer can run to observe the new behavior, describe them.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. See Running tests for more details
  • Self-reviewed the diff
  • Changelog fragment added in .changes/

@carbolymer carbolymer force-pushed the mgalazyn/feature/rpc-fetchblock-add-timestamp branch from 4cc7e51 to 3ef4994 Compare July 6, 2026 17:49
@carbolymer carbolymer marked this pull request as ready for review July 6, 2026 17:49
@carbolymer carbolymer requested a review from Jimbo4350 as a code owner July 6, 2026 17:49
Copilot AI review requested due to automatic review settings July 6, 2026 17:49
@carbolymer carbolymer self-assigned this Jul 6, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the cardano-rpc FetchBlock SyncService implementation to populate Block.timestamp, by deriving a slot timestamp using SystemStart plus an EraHistory computed from the node’s ledger state. To support this from cardano-rpc, it also expands Cardano.Api.Consensus re-exports for node-kernel access.

Changes:

  • Extend NodeKernelAccess to carry SystemStart and an IO-backed readEraHistory action, enabling slot-to-UTC conversion when serving FetchBlock.
  • Populate Block.timestamp (milliseconds since epoch) in the FetchBlock handler and update docs to reflect the feature.
  • Add additional consensus re-exports (and changelog fragments) to support the new node-kernel/ledger-era-history functionality.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess/Type.hs Extend the node-kernel handle with systemStart and readEraHistory (and rename the ChainDB field).
cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs Build the extended NodeKernelAccess from TopLevelConfig + NodeKernel; adjust block fetch helper to use renamed field.
cardano-rpc/src/Cardano/Rpc/Server/Internal/UtxoRpc/Sync.hs Compute and populate Block.timestamp during FetchBlock responses.
cardano-rpc/README.md Mark FetchBlock as no longer missing Block.timestamp.
cardano-api/src/Cardano/Api/Consensus/Internal/Reexport.hs Expand internal consensus re-exports used by Cardano.Api.Consensus.
cardano-api/src/Cardano/Api/Consensus.hs Re-export additional consensus/node-kernel symbols from the public Cardano.Api.Consensus module.
.changes/20260602_cardano_rpc_fetchblock.yml Update changelog fragment text for the FetchBlock timestamp work.
.changes/20260602_cardano_api_consensus_reexports.yml Update changelog fragment text for additional consensus re-exports.

Comment thread cardano-rpc/src/Cardano/Rpc/Server/NodeKernelAccess.hs
Comment thread cardano-api/src/Cardano/Api/Consensus/Internal/Reexport.hs
- compatible
description: |
Re-export consensus types from Cardano.Api.Consensus for node kernel access: NodeKernel, ChainDB, BlockComponent, RealPoint, OneEraHash, HeaderHash, HasHeader, BlockType, StandardCrypto, CardanoBlock, blockNo.
Re-export consensus types from Cardano.Api.Consensus for node kernel access: NodeKernel, ChainDB, BlockComponent, RealPoint, OneEraHash, HeaderHash, HasHeader, BlockType, StandardCrypto, CardanoBlock, blockNo, getCurrentLedger, TopLevelConfig, configLedger, configBlock, ledgerState, HasHardForkHistory(..), ConfigSupportsNode, nodeSystemStart, mkInterpreter.
Comment on lines +48 to +59
throwPastHorizon =
throwGrpcErrorWithMessage GrpcInternal $
"past horizon converting slot " <> tshow (unSlotNo slot) <> " to timestamp"
headerHash <-
deserialiseFromRawBytes (proxyToAsType (Proxy @(Hash BlockHeader))) hashBytes
& either (const throwInvalidHash) pure
(rawBytes, BlockNo height) <-
fetchBlock nodeKernelAccess slot headerHash >>= maybe throwNotFound pure
eraHistory <- readEraHistory
timestampMs <-
slotToUTCTime systemStart eraHistory slot
& either (const throwPastHorizon) (pure . round . (* 1000) . utcTimeToPOSIXSeconds)

@carbolymer carbolymer Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't gain any extra info from it, and the showed exception is quite verbose

Comment on lines +56 to +59
eraHistory <- readEraHistory
timestampMs <-
slotToUTCTime systemStart eraHistory slot
& either (const throwPastHorizon) (pure . round . (* 1000) . utcTimeToPOSIXSeconds)
- breaking
description: |
Implement FetchBlock SyncService method via node kernel access. Fetches blocks from ChainDB with raw CBOR bytes and cardano block header (slot, hash, height). Breaking: `runRpcServer` signature now takes `IORef (Maybe NodeKernelAccess)` for node kernel access.
Implement FetchBlock SyncService method via node kernel access. Fetches blocks from ChainDB with raw CBOR bytes, cardano block header (slot, hash, height), and timestamp (slot-to-UTC conversion via EraHistory). Breaking: `runRpcServer` signature now takes `IORef (Maybe NodeKernelAccess)` for node kernel access.
Comment on lines 79 to 83
, getOpCertCounters
, interpreterToEpochInfo
, mkInterpreter
, unsafeExtendSafeZone
, txId

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bullcrap

@carbolymer carbolymer force-pushed the mgalazyn/feature/rpc-fetchblock-add-timestamp branch from 3ef4994 to 73e1a16 Compare July 7, 2026 15:26

@Jimbo4350 Jimbo4350 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, a couple minor comments.

import Ouroboros.Consensus.Util.Condense (condense)

-- | Extract the network system start time from the node's top-level configuration.
nodeSystemStart :: ConfigSupportsNode blk => TopLevelConfig blk -> SystemStart

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be better suited in Cardano.Api.Consensus or some other adjacent module as it's not strictly a re-export.

"block not found at slot " <> tshow (unSlotNo slot)
throwPastHorizon =
throwGrpcErrorWithMessage GrpcInternal $
"past horizon converting slot " <> tshow (unSlotNo slot) <> " to timestamp"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a hint as to how a user would correct this error in the error message?

{ nkaChainDB :: Consensus.ChainDB IO (Consensus.CardanoBlock Consensus.StandardCrypto)
{ chainDb :: Consensus.ChainDB IO (Consensus.CardanoBlock Consensus.StandardCrypto)
-- ^ Handle to the consensus chain database
, systemStart :: SystemStart

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like:

- ^ Network system start time, extracted from genesis config.
  -- Used together with 'readEraHistory' to convert slots to wall-clock
  -- time

Would be useful.

@carbolymer carbolymer force-pushed the mgalazyn/feature/rpc-fetchblock-add-timestamp branch from 534dce1 to 15431b7 Compare July 10, 2026 09:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants