Skip to content

feat: add midnight_queryContractState RPC for lazy contract state access#1078

Open
RomarQ wants to merge 8 commits intomidnightntwrk:mainfrom
RomarQ:feat/query-contract-state-v2
Open

feat: add midnight_queryContractState RPC for lazy contract state access#1078
RomarQ wants to merge 8 commits intomidnightntwrk:mainfrom
RomarQ:feat/query-contract-state-v2

Conversation

@RomarQ
Copy link
Copy Markdown
Contributor

@RomarQ RomarQ commented Mar 25, 2026

Overview

Add a new RPC method midnight_queryContractState that queries specific fields from a contract's state tree by path, without loading the full state. This enables clients to fetch individual contract fields in O(log n) instead of deserializing the entire state blob.

Each query navigates the state tree using serialized AlignedValue keys (array index, map key, or merkle tree position), mirroring the VM's idx instruction.

The RPC reads the state key via a minimal runtime API getter (get_state_key), then calls the bridge directly for O(log n) lazy navigation of the contract state in ParityDB. No new types cross the WASM boundary.

Changes

  • ledger: add resolve_state_path (single path navigation) and query_contract_state (batch) bridge functions, exposed via a dedicated rpc module
  • runtime_api: add get_state_key getter (bumps api_version to 6)
  • runtime: implement get_state_key
  • rpc: add midnight_queryContractState endpoint with input validation (MAX_STATE_QUERIES=100, MAX_PATH_DEPTH=16)

📌 Submission Checklist

  • Changes are backward-compatible (or flagged if breaking)
  • Pull request description explains why the change is needed
  • Self-reviewed the diff
  • I have included a change file, or skipped for this reason: draft PR for internal review
  • If the changes introduce a new feature, I have bumped the node minor version
  • No new todos introduced

🧪 Testing Evidence

Added tests to tests/e2e/tests/lib.rs and tested it manually in project I have been working on the side https://github.com/RomarQ/midnight-rs

🔱 Fork Strategy

  • Node Runtime Update (This could be avoided, by having the key hard-coded, but I think extending the runtime API with get_state_key() is probably the best approach)
  • Node Client Update

Links

RomarQ and others added 3 commits March 25, 2026 12:07
Add a new RPC method that queries specific fields from a contract's state
tree by path, without loading the full state. Each query navigates the
state tree using serialized AlignedValue keys (array index, map key, or
merkle tree position), mirroring the VM's idx instruction.

The RPC reads the state key via a minimal runtime API getter
(get_state_key), then calls the bridge directly for O(log n) lazy
navigation of the contract state in ParityDB.

Changes:
- ledger: add resolve_state_path and query_contract_state bridge functions
- ledger: expose query_contract_state via a dedicated rpc module
- runtime_api: add get_state_key getter (bumps api_version to 6)
- runtime: implement get_state_key
- rpc: add midnight_queryContractState endpoint with input validation
Import RpcStateQuery/RpcStateQueryResult from pallet-midnight-rpc.
Add query_contract_state method to MidnightClient.

Tests deploy the test contract via DEPLOY_TX then exercise the RPC:
- returns_expected_value: query path [0][1], deserialize, assert Cell(0u64)
- batch_processes_all_queries: three queries in one call covering
  Cell value ([0][1] = 0u64), map hit ([0][2][key] = Null),
  and array out-of-bounds error ([0][99])
- nonexistent_contract: assert "Unable to query contract state" error
@RomarQ RomarQ marked this pull request as ready for review March 25, 2026 14:53
@RomarQ RomarQ requested a review from a team as a code owner March 25, 2026 14:53
RomarQ added 4 commits March 25, 2026 16:36
Replace Vec<String> with Vec<sc_client_api::StorageKey> in
RpcStateQuery. StorageKey handles 0x-prefixed hex encoding at
the serde layer, removing the need for manual hex decode on the
server side.

Also removes the BadQueryKey and QueryContractStateNotSupported
error variants which are no longer needed.
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.

Feature Request: Lazy contract state queries via RPC

1 participant