Feature: Expose lightweight ParticipantWeight query to CosmWasm (AcceptedGrpcQueries) #1867
Summary
I am working on an open-source compute weight swap and escrow mechanism for the Gonka network (GonkaWeightSwap), which allows node operators and capital providers to trustlessly agree on compute weight delivery in exchange for USDT, completely within the Gonka protocol (no external oracles or trusted off-chain relayers).
To enable CosmWasm contracts to verify performance on-chain, contracts need to read two core metrics: 1. The current / completed epoch number. 2. The weight achieved by a specific participant address in a given epoch.
To introduce the concept, the motivation, and how this expands the Gonka ecosystem, I have prepared a video pitch: 🎥 Video Pitch & Concept Overview: https://youtu.be/L3RNyd-STwo
Motivation & Use Case
Currently, connecting hardware operators with outside capital relies heavily on off-chain trust, manual settlements, or complex legal agreements.
An on-chain escrow contract solves this by locking investor funds and releasing them dynamically as node operators deliver verified weight to the investor's designated address. However, CosmWasm currently cannot query the inference module's epoch/weight state directly.
Why Not Just Allowlist EpochGroupData?
While /inference.inference.Query/EpochGroupData exists, having a CosmWasm contract query and deserialize the entire participant array has major drawbacks:
- O(N) Gas & Memory Overhead: As the network grows to hundreds or thousands of participants, passing the full array into the WASM runtime will exceed contract gas limits or cause out-of-memory errors.
- Contract Complexity: Parsing huge protobuf messages inside CosmWasm contracts creates unnecessary friction and gas waste for end users.
Proposed Solution: Targeted O(1) Query
I propose adding a lightweight, gas-efficient endpoint to the inference query service and exposing it to CosmWasm:
- New query method in x/inference:
- Method:
rpc ParticipantWeight(QueryParticipantWeightRequest) returns (QueryParticipantWeightResponse); - Request:
uint64 epoch,string participant - Response:
uint64 weight,bool found -
Implementation detail: This directly looks up the participant in the epoch's KV store in O(1) time without serializing the rest of the network's participants.
-
Allowlist in x/wasm (AcceptedGrpcQueries):
/inference.inference.Query/GetCurrentEpoch/inference.inference.Query/ParticipantWeight
Benefits to Gonka
- Zero Security Risk: Both queries are strictly read-only against already finalized KV storage.
- Gas & Network Safe: Constant-time execution prevents block bloat and gas exhaustion attacks.
- Ecosystem Growth: Unlocks a decentralized market for compute rentals, attracts external capital into node operations, and encourages hardware competition.
Next Steps
I would love to get your feedback on this approach!
I am happy to collaborate with the core team, share more details on the product mechanics, and discuss how this feature solves real liquidity and compute allocation challenges for Gonka participants.
💬 Comments (4)
-
Yes, this looks feasible. The summary is created during epoch settlement, so it is a good place to store the final weight.
-
We can use the existing query. No new endpoint is needed.
-
- We already calculate ParticipantRewardWeight after caps, penalties, and delegation reward transfers. We should confirm if this is the weight GonkaWeightSwap needs.
-
The query uses the participant address. A separate reward recipient does not get that participant’s summary.
-
We also need to handle old epochs: a missing weight must not be treated as a real zero.
- For GonkaWeightSwap, do you need confirmed compute weight or the final weight used for rewards?
Thanks so much for the quick and insightful feedback, @niktverd! This is super helpful.
Here are the specifics regarding our use case:
-
Weight type (
ParticipantRewardWeightvs compute weight):ParticipantRewardWeight(the final weight used for rewards) is exactly what GonkaWeightSwap needs. The core purpose of the escrow is to ensure the investor pays for actual, rewarded network contribution. If a node suffers penalties, slashing, or caps during the epoch, the escrow settlement should reflect the net rewarded weight rather than raw compute. Havingreward_weight(and optionally raw compute weight if convenient) inEpochPerformanceSummaryfits this perfectly. -
Participant address vs reward recipient: Thank you for highlighting this! Since the deal in the escrow contract tracks both parties (the host operator and the investor), the contract can directly query by the host's
participantaddress to verify the epoch performance. -
Handling legacy epochs: Makes total sense. On the contract side, we will ensure that settlement only queries epochs from the agreement start onwards, and will treat unpopulated/legacy values as unsupported rather than an intentional zero.
Would you prefer to include this field update directly in upgrade-v0.2.16, or would it help if I opened a PR against the upgrade branch?
Really appreciate your help and guidance on this!
Hi @niktverd! As discussed, I opened a PR targeting upgrade-v0.2.16 to record ParticipantRewardWeight in EpochPerformanceSummary:
https://github.com/gonka-ai/gonka/pull/#1925
Looking forward to your review and feedback!
🔄 Auto-synced from Issue #1867 every hour.
Following up on this: I noticed that PR #1758, merged into
upgrade-v0.2.16, already exposesGetCurrentEpochandEpochPerformanceSummaryByParticipantto CosmWasm. This is a very important step for marketplace and escrow-style contracts.Looking at the current protobuf definition,
EpochPerformanceSummaryalready provides per-participant stats for a completed epoch, including inference counts, rewards, missed requests, and claim status. However, it does not currently include the participant's finalized computeweight.Proposed option
Instead of introducing a completely new query endpoint, would it be feasible to extend the existing
EpochPerformanceSummarywith a weight field?This would allow a CosmWasm contract to read, through the already exposed
EpochPerformanceSummaryByParticipantquery:Why this may be the simplest approach
EpochPerformanceSummaryByParticipantis already a targeted per-participant, per-epoch lookup rather than a full-network participant list.For GonkaWeightSwap specifically, the contract needs the finalized weight of the configured reward-recipient address in order to determine whether the host met the agreed delivery conditions.
Would adding
weighttoEpochPerformanceSummarybe feasible for an upcoming upgrade? I would be very interested in the view on whether this fits the intended meaning and lifecycle of this record.cc @niktverd