Skip to content

fix(utxorpc): convert block timestamp from seconds to ms in u5c mapping - #793

Open
stnly-btcdefi wants to merge 1 commit into
txpipe:mainfrom
stnly-btcdefi:fix/u5c-block-timestamp-ms
Open

fix(utxorpc): convert block timestamp from seconds to ms in u5c mapping#793
stnly-btcdefi wants to merge 1 commit into
txpipe:mainfrom
stnly-btcdefi:fix/u5c-block-timestamp-ms

Conversation

@stnly-btcdefi

@stnly-btcdefi stnly-btcdefi commented Jul 30, 2026

Copy link
Copy Markdown

A sixth site of the seconds-vs-milliseconds timestamp mismatch fixed in txpipe/dolos#1003: the u5c Mapper writes LedgerContext::get_slot_timestamp's seconds-typed value straight into Block.timestamp, which the utxorpc spec declares as milliseconds.

What the proto says

utxorpc/spec declares cardano.Block.timestamp as milliseconds (// Block ms timestamp), same as the four ChainPoint/BlockRef sites dolos#1003 covered.

What the mapper actually writes

pallas-utxorpc/src/shared.rs (map_block, shared by the v1alpha and v1beta mappers):

timestamp: self
    .ledger
    .as_ref()
    .and_then(|ledger| ledger.get_slot_timestamp(block.slot()))
    .unwrap_or(0),

LedgerContext::get_slot_timestamp is documented as UNIX seconds (pallas-utxorpc/src/lib.rs), and implementations follow that contract — so every parsed block flowing through the mapper (Dolos SyncService.FollowTip / DumpHistory among others) carries a seconds value in a ms field.

Observed downstream against Dolos sha-c469c7f on preprod: a block at slot ~125.54M arrived with timestamp ≈ 1_781_253_xxx. Read as seconds that decodes to 2026-06-12, which matches the slot arithmetic (preprod system start 2022-06-01, 20-day Byron era at 20s slots, 1s slots after) to the day; read as ms per spec it decodes to 1970-01-21, which is how our chain-follower's e2e caught it.

The fix

Same principle as dolos#1003: convert at the proto write boundary, keep the trait untouched — its seconds contract is documented and correctly implemented. One functional line:

.map(|seconds| seconds * 1000)

A missing timestamp stays 0 (proto3 default), unchanged.

Verification

cargo test -p pallas-utxorpc green. With the multiplication in place the observed preprod values decode to the same wall-clock dates as the slot math — the conversion promotes units, it does not reinterpret anything.

Summary by CodeRabbit

  • Bug Fixes
    • Corrected block timestamps to use millisecond precision.
    • Preserved a fallback timestamp when ledger timing data is unavailable.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The shared Cardano block mapper now converts ledger-provided UNIX timestamps from seconds to milliseconds before populating BlockBody.timestamp, while retaining 0 when no timestamp is available.

Changes

Block timestamp mapping

Layer / File(s) Summary
Convert mapped timestamps to milliseconds
pallas-utxorpc/src/shared.rs
map_block multiplies the optional ledger timestamp by 1000 before assigning BlockBody.timestamp and preserves the 0 fallback.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • txpipe/pallas#693: Adds the ledger slot timestamp used by map_block, which this change converts from seconds to milliseconds.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: converting UTxO RPC block timestamps from seconds to milliseconds in the u5c mapping.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@stnly-btcdefi
stnly-btcdefi force-pushed the fix/u5c-block-timestamp-ms branch from 3da2662 to ba053d3 Compare July 30, 2026 14:36
@stnly-btcdefi
stnly-btcdefi marked this pull request as ready for review July 30, 2026 14:37

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
pallas-utxorpc/src/shared.rs (1)

464-471: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add regression coverage for both timestamp paths.

Please add tests asserting seconds-to-milliseconds conversion and that a missing ledger timestamp still maps to 0; this protects the wire-unit contract from future regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pallas-utxorpc/src/shared.rs` around lines 464 - 471, Add regression tests
for the timestamp construction around get_slot_timestamp: cover a present ledger
timestamp and assert UNIX seconds are converted to milliseconds, then cover an
absent ledger timestamp and assert the resulting Block.timestamp is 0. Reuse the
existing test setup and inspect the produced timestamp field to preserve both
wire-unit paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pallas-utxorpc/src/shared.rs`:
- Around line 464-471: Add regression tests for the timestamp construction
around get_slot_timestamp: cover a present ledger timestamp and assert UNIX
seconds are converted to milliseconds, then cover an absent ledger timestamp and
assert the resulting Block.timestamp is 0. Reuse the existing test setup and
inspect the produced timestamp field to preserve both wire-unit paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 62be5a6e-3c8f-4b11-aa9e-b2bacf9497d8

📥 Commits

Reviewing files that changed from the base of the PR and between cdee91d and ba053d3.

📒 Files selected for processing (1)
  • pallas-utxorpc/src/shared.rs

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.

1 participant