Conversation
Lands the first slice of M12.P1: the LocalStateQuery (id 7) wire codec, acquire/release/close driver surface, and the N2C handshake's `query=true` flip on `LocalNodeProvider.connect`. The typed query/result GADT and the `fetchLatestParams`/`findUtxos`/`currentSlot` impls land in P1.b. Includes a small `CborMessageStream` enhancement: thread `OriginalCborByteArray` through to the per-decode `Decoder[M]` synthesis so message decoders can capture raw CBOR slices (LSQ `MsgResult`, anything wrapped in `KeepRaw[A]`). Existing context-free `Decoder[M]` givens auto-lift; all 249 existing tests pass unchanged. Codec follows the borer-#761 raw-bytes splice pattern proven by scalus's `KeepRaw`: `w.output.writeBytes(...)` on encode, `r.skipElement()` + cursor math on decode. 22 round-trip + golden-bytes + malformed-input tests cover every message variant.
- collapse `writeAcquire(w, atTag, tipTag, immutableTag, target)` 4-arg helper into inline pattern matches at the two call sites - extract `writeRawBodyMessage(w, tag, bytes)` for the MsgQuery / MsgResult cases (differ only in the int tag) - trim doc-comments that paraphrased their type signatures - drop in-source phase-name references (P1.b / "deferred") — those belong in commit messages, not error strings or state-machine diagrams
… (M12.P1.b) - new LsqQuery GADT with GetChainPoint (top-level [3]); per-query result decoder dispatches via GADT pattern match - LocalStateQueryDriver gains query[A](q): Future[A] — encodes typed query via the established raw-bytes splice path, awaits MsgResult, decodes - LocalStateQueryDriver.release() optimistically resets `acquired = false` before send so a mid-release wire failure surfaces as a connection error on the next acquire, not a stale "already acquired" guard - LocalNodeProvider.connect spawns LSQ driver alongside LTS; close() tears both down - currentSlot replaced with acquire(VolatileTip) → query(GetChainPoint) → release sequence, serialised by an async-mutex over the LSQ driver - getDatum returns Future.successful(None) — LSQ has no datum-by-hash - fetchLatestParams / findUtxos / checkTransaction still raise; they need per-era PParams / UTxO / Tx-status CBOR decoders that aren't wired in scalus-cardano-ledger today
Contributor
There was a problem hiding this comment.
Pull request overview
Adds initial Node-to-Client LocalStateQuery (LSQ) support to the network layer, including message framing/codecs, a minimal typed query GADT, an initiator-side driver, and wiring into LocalNodeProvider to back currentSlot via LSQ.
Changes:
- Introduce LSQ message ADT + CBOR codec (including raw CBOR splicing/capture for query/result bodies).
- Add
LocalStateQueryDriverwithacquire/query/release/closeand a minimalLsqQuery(GetChainPoint) with typed result decoding. - Update
CborMessageStreamto support decoders that depend on the active CBOR buffer (OriginalCborByteArray), and wireLocalNodeProvider.currentSlotthrough LSQ (handshakequery = true).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| scalus-cardano-network/shared/src/test/scala/scalus/cardano/network/n2c/localstatequery/LsqQuerySuite.scala | Adds golden/round-trip tests for LsqQuery.GetChainPoint encoding and result decoding. |
| scalus-cardano-network/shared/src/test/scala/scalus/cardano/network/n2c/localstatequery/LocalStateQueryMessageSuite.scala | Adds round-trip, golden bytes, and malformed-input tests for LSQ message codecs. |
| scalus-cardano-network/shared/src/main/scala/scalus/cardano/network/n2c/localstatequery/LsqQuery.scala | Defines the typed LSQ query GADT and result decoding (currently GetChainPoint). |
| scalus-cardano-network/shared/src/main/scala/scalus/cardano/network/n2c/localstatequery/LocalStateQueryMessage.scala | Implements LSQ protocol messages and a hand-written CBOR codec including raw-body splicing/capture. |
| scalus-cardano-network/shared/src/main/scala/scalus/cardano/network/n2c/localstatequery/LocalStateQueryDriver.scala | Adds initiator-side LSQ driver with state guards and typed query. |
| scalus-cardano-network/shared/src/main/scala/scalus/cardano/network/infra/CborMessageStream.scala | Makes decoding buffer-aware via OriginalCborByteArray + lazy decoderProvider resolution. |
| scalus-cardano-network/jvm/src/main/scala/scalus/cardano/network/n2c/LocalNodeProvider.scala | Wires LSQ into the provider (currentSlot) with serialized acquire/query/release and enables handshake query=true. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+21
to
+25
| * Owns its own [[NodeToClientConnection]] plus three mini-protocol drivers: | ||
| * - [[LocalTxSubmissionDriver]] on [[MiniProtocolId.LocalTxSubmission]] for `submit` | ||
| * - [[LocalStateQueryDriver]] on [[MiniProtocolId.LocalStateQuery]] for `currentSlot` and | ||
| * (eventually) the rest of the read surface | ||
| * - [[LocalTxSubmissionDriver]]'s connection-root for KeepAlive |
Comment on lines
+57
to
+61
| // Decoder is resolved lazily per decode so message types whose decoders depend on the | ||
| // active CBOR buffer (`given OriginalCborByteArray` — see `KeepRaw[A]` and the LSQ | ||
| // `MsgResult` decoder) get the right buffer in scope. Callers with a context-free | ||
| // `Decoder[M]` are auto-lifted by the compiler. | ||
| decoderProvider: OriginalCborByteArray ?=> Decoder[M], |
Comment on lines
+27
to
+28
| * Today this driver implements `acquire` / `release` / `close`; `query[A]` and `reAcquire` land | ||
| * alongside the `LsqQuery` GADT in a follow-up. |
Comment on lines
164
to
166
| cardanoInfo: CardanoInfo, | ||
| submitEra: Int = 6 | ||
| )(using ExecutionContext): Future[LocalNodeProvider] = { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.