You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every UTxO RPC service includes a google.protobuf.FieldMask in its request messages, letting clients select which response fields the server should materialise.
cardano-rpc currently ignores it everywhere; the only trace is a TODO in readParamsMethod (Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs), which notes that masks need to be normalised before use, following the semantics of protobuf's FieldMaskTree.
Bandwidth: responses like AnyChainBlock carry both raw CBOR (native_bytes) and the fully parsed cardano block.
A client interested only in headers, or only in raw bytes, currently receives everything. gRPC: Implement FollowTip (UTxO RPC SyncService) in cardano-rpc #1219 already flags this ("FieldMask becomes valuable for letting clients request only headers, or only transaction hashes").
An absent or empty mask means "return all fields" (standard FieldMask read semantics); current behaviour is therefore already correct for clients that send no mask.
A non-empty mask is normalised first (deduplicate, drop paths covered by an ancestor path), following the semantics of protobuf's FieldMaskTree linked above.
The mask drives response construction, not post-hoc pruning: handlers consult the mask before doing the work behind each field, so data that is masked out is never fetched, decoded, or converted in the first place.
Building the full response and then stripping fields would deliver the bandwidth win but none of the server-side cost win, which is the harder and more valuable half.
Invalid paths: follow the protobuf recommendation for read masks - ignore unknown paths rather than failing the request (to be confirmed against what other UTxO RPC servers, e.g. Dolos, do).
Implementation sketch
A shared mask-query helper in cardano-rpc: normalise a FieldMask into a path tree and expose "is this path (or any child of it) requested?" for handlers to branch on.
Wire it into the implemented handlers (ReadParams, ReadUtxos, SearchUtxos, ReadGenesis, FetchBlock, FollowTip): each expensive field (protocol parameter conversion, UTxO parsing, tx conversion) is computed only when its path is requested.
FollowTip/FetchBlock fetch-avoidance: when the mask excludes all parsed cardano.* paths, fetch only GetRawBlock and skip GetBlock; when it excludes native_bytes, fetch only GetBlock.
This changes the BlockComponent selected in NodeKernelAccess, so the follower/fetch component becomes a function of the request.
Unmentioned future handlers (ReadEraSummary, ReadData, ReadTx, DumpHistory, WatchMempool) apply the same helper when they land.
Acceptance criteria
Empty/absent mask returns full responses (no behaviour change for existing clients).
Masked unary responses contain only the requested paths, with mask normalisation applied.
FollowTip and FetchBlock skip the block decode when the mask excludes all parsed block fields, and skip raw-bytes fetch when the mask excludes native_bytes.
Unknown mask paths are handled per the documented policy (ignored or rejected - decided and documented).
Unit tests cover mask normalisation and masked response construction; conformance checked against another UTxO RPC server (e.g. Dolos) via the existing comparison tooling.
README coverage table updated to note FieldMask support.
Out of scope
Field masks on methods not yet implemented (they inherit the helper when implemented).
Write masks / update semantics (FieldMask is used purely as a read mask in UTxO RPC).
Context
Every UTxO RPC service includes a
google.protobuf.FieldMaskin its request messages, letting clients select which response fields the server should materialise.cardano-rpc currently ignores it everywhere; the only trace is a TODO in
readParamsMethod(Cardano/Rpc/Server/Internal/UtxoRpc/Query.hs), which notes that masks need to be normalised before use, following the semantics of protobuf'sFieldMaskTree.Request messages carrying a
field_mask:ReadParamsRequestReadUtxosRequestSearchUtxosRequestReadGenesisRequestReadEraSummaryRequestReadDataRequestReadTxRequestFetchBlockRequestFollowTipRequestDumpHistoryRequestWatchMempoolRequestMotivation
Two distinct wins:
AnyChainBlockcarry both raw CBOR (native_bytes) and the fully parsedcardanoblock.A client interested only in headers, or only in raw bytes, currently receives everything.
gRPC: Implement FollowTip (UTxO RPC SyncService) in cardano-rpc #1219 already flags this ("
FieldMaskbecomes valuable for letting clients request only headers, or only transaction hashes").FetchBlockand everyFollowTipstream fetch two block components per block,GetRawBlockandGetBlock, and theGetBlockdecode is paid unconditionally.A mask excluding the parsed
cardanofields would let the server select theBlockComponentper request and skip block deserialisation entirely.Proposed behaviour
FieldMaskread semantics); current behaviour is therefore already correct for clients that send no mask.FieldMaskTreelinked above.Building the full response and then stripping fields would deliver the bandwidth win but none of the server-side cost win, which is the harder and more valuable half.
Implementation sketch
FieldMaskinto a path tree and expose "is this path (or any child of it) requested?" for handlers to branch on.ReadParams,ReadUtxos,SearchUtxos,ReadGenesis,FetchBlock,FollowTip): each expensive field (protocol parameter conversion, UTxO parsing, tx conversion) is computed only when its path is requested.FollowTip/FetchBlockfetch-avoidance: when the mask excludes all parsedcardano.*paths, fetch onlyGetRawBlockand skipGetBlock; when it excludesnative_bytes, fetch onlyGetBlock.This changes the
BlockComponentselected inNodeKernelAccess, so the follower/fetch component becomes a function of the request.ReadEraSummary,ReadData,ReadTx,DumpHistory,WatchMempool) apply the same helper when they land.Acceptance criteria
FollowTipandFetchBlockskip the block decode when the mask excludes all parsed block fields, and skip raw-bytes fetch when the mask excludesnative_bytes.FieldMasksupport.Out of scope
FieldMaskis used purely as a read mask in UTxO RPC).