Skip to content

feat(cardano): make FetchBlock and ReadData single-item operations - #213

Merged
scarmuega merged 1 commit into
utxorpc:mainfrom
carbolymer:sync-fetchblock-single-block
Sep 14, 2026
Merged

scarmuega merged 1 commit into
utxorpc:mainfrom
carbolymer:sync-fetchblock-single-block

Conversation

@carbolymer

Copy link
Copy Markdown
Contributor

Summary

  • Remove repeated from FetchBlockRequest.ref and FetchBlockResponse.block, making FetchBlock a single-block operation.
  • Remove repeated from ReadDataRequest.keys and ReadDataResponse.values (now key and value), making ReadData a single-datum operation.
  • Target the new v1 package; v1beta and v1alpha are untouched.
  • ReadUtxos keeps its batched shape on purpose, see below.

Motivation

These RPCs are per-item lookups, but the batched responses had no per-item error channel.
When one item could not be resolved, a server could only fail the whole call or silently omit the item, and the client could not tell omission from an error.
Existing implementations confirm the problem: Dolos fails the whole FetchBlock call on the first unresolvable ref, and dingo aborts both FetchBlock and ReadData on the first miss.
With single-item requests, the gRPC status code applies unambiguously to the one requested item.

Batching also bought nothing here, on either axis:

  • Performance: no implementation resolves these lists in a single storage operation. Dolos loops sequentially per block ref, dingo loops per point and per datum key, and cardano-node-api's FetchBlock handler is stubbed out. Concurrent single requests multiplexed over one HTTP/2 connection cost about the same as those loops.
  • Consistency: both methods read immutable, content-addressed data. A block fetched by hash and a datum fetched by its hash cannot change between requests, so a multi-item request carries no consistency guarantee that concurrent single requests lack.

This follows the same approach as #163, which made SubmitTx and EvalTx singular.

Why ReadUtxos is not following suit

ReadUtxos is the only one of the three that queries mutable ledger state, and its repeated keys field buys two things single-item requests cannot replicate:

  1. A real batch primitive. Cardano's local state query protocol resolves a set of TxIns in one ledger query (GetUTxOByTxIn), and implementations use it: cardano-node-api forwards the whole key list in a single N2C query, and dingo resolves all refs in one batched SQL query. Splitting into singles turns one lookup into N.
  2. Atomicity. Requests cannot pin a chain point, so a batched request is the only way to read N UTxOs against one consistent ledger view. With singles, ledger_tip only lets a client detect after the fact that its reads straddled a tip change.

The absent-vs-failed ambiguity described above affects ReadUtxos too, but it can be fixed without giving up batching: each response item could state explicitly whether the key was found (carrying the UTxO) or missing (echoing the key), so absence becomes an answer instead of a silence.
That is left out of scope for this PR.

Breaking change

This is a wire-incompatible change to the v1 package.
v1 is freshly initialised (565b990) and unreleased, so no published consumers are affected; v1beta and v1alpha are untouched.

@scarmuega
scarmuega merged commit 0dbb1ec into utxorpc:main Sep 14, 2026
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.

2 participants