Skip to content

gRPC: Guard against fetching the entire UTxO set in ReadUtxos and SearchUtxos #1195

@carbolymer

Description

@carbolymer

Problem

Both ReadUtxos and SearchUtxos can fall back to QueryUTxOWhole, which fetches the entire UTxO set from the node into memory. On mainnet this is millions of entries and can be very expensive per request.

ReadUtxos

When keys is empty, readUtxosMethod falls back to QueryUTxOWhole:

utxoFilter <-
  if not (null $ req ^. U5c.keys)
    then QueryUTxOByTxIn . fromList <$> mapM txoRefToTxIn (req ^. U5c.keys)
    else pure QueryUTxOWhole

Every other UTxO RPC implementation (Dolos, cardano-node-api, Dingo) returns an empty response when no keys are provided. None of them fall back to fetching the whole set.

SearchUtxos

When extractAddressesFromPredicate returns Nothing (which includes predicates using paymentPart, delegationPart, asset-only patterns, not, or allOf), searchUtxosMethod also falls back to QueryUTxOWhole:

let utxoFilter = case mPredicate >>= extractAddressesFromPredicate of
      Just addrs -> QueryUTxOByAddress addrs
      _ -> QueryUTxOWhole

For comparison:

  • Dolos rejects broad predicates: "criteria too broad, narrow it down"
  • cardano-node-api rejects empty predicates
  • Dingo allows it but has database-level pagination, so the full set is never materialised in memory

Suggested fix

  • ReadUtxos: return an empty response when keys is empty, matching other implementations.
  • SearchUtxos: either reject predicates that cannot be narrowed to specific addresses, or document this as a known limitation until a more efficient query path exists (e.g. database-backed storage like Dingo).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions