[P0] `devshards` rewards (research) #914
Priority: High devshards
Tasks
- Calculate what the fee on
devshardsshould be for differentdevshardsizes - Decide what we're going to implement
- Implement: (tentative plan)
- Calculate and charge fee for
devshards- Initial impl: create_fee + max_nonce * fee_per_nonce
- Charging per nonce -> mechanism to deter from spamming the network with small inf requests
- Ensure escrow amount covers the fee
- Ensure the escrow balance never goes below the fee
- Charge the fee upon settlement
- Initial impl: create_fee + max_nonce * fee_per_nonce
- Distribute
WorkCoinsat the end of the epoch, instead of upon settlement. - Take
devshardstats into account when calculating punishmentsWorkCoins/RewardCoins
- Calculate and charge fee for
Research
💬 Comments (3)
Meeting Notes 2026/03/19
- Total RewardCoins for one whole epoch is 300k GNK, split by weight across all ACTIVE participants.
- Let's say the dishonest actor has to create 3k
devshardsto be able to exploit one (with 99% confidence) -
The total cost to create 3k
devshardsshould be 300k GNK- It's a function of 300k and the
devshardssize - 300k is equal to the maximum damage the actor can do
- It's a function of 300k and the
-
Limiting
Missed/Invalidated: For now, let's say eachdevshardscan run up to 2k inferences.
The research part will be in Progress, but doesn't block the implementation.
🔄 Auto-synced from Issue #914 every hour.
Current situation
There are 2 kinds of rewards for inferences done on-chain (outside of
devshards): *WorkCoins: transferred from the user to hosts. It's a direct payment for work done running inferences. *RewardCoins: mined coins distributed to hosts, proportional to their weight. * These do not increase/decrease with the number of inferences done. * Above a certain threshold ofMissedinferences,RewardCoinsmay be cut to 0. * See:CheckAndPunishForDowntimeForParticipants* Additionally, ifMissedinferences orInvalidatedinferences are above certain threshold, the protocol will mark the host asParticipantStatus_INACTIVEorParticipantStatus_INVALID, and both theirWorkCoinsandRewardCoinswill also be cut to 0. * Seestatus.go:ComputeStatus,getInvalidationStatus,getInvalidationStatusAt the moment: *
devshardssettlements distributeWorkCoinsimmediately after settlement * This distribution does not takeINACTIVE/INVALIDstatuses into account *devshardsstats don't count towardsRewardCoinsGoals
We want to treat
devshardssettlements the same way as onchain inferences. * Thedevshards's stats (Missed/Invalidated) should count towards setting the host asINACTIVE/INVALID, and thus potentially cutting both theirWorkCoinsandRewardCoins*WorkCoinsshould be distributed at the end of the epoch, rather than immediatelyAttack vectors
When a dishonest host hijacks a
devshards, they can: * Manipulate their ownSubnetSettlementHostStats.Cost. * They can exploit this to drain the user's escrow, without spending GPU power on running inferences * This profit is currently limited: the protocol checks thatCostcannot exceed the escrow amount. See:VerifySubnetSettlement* Manipulate other host'sSubnetSettlementHostStats.Invalid* This damage is not currently limited,SettleSubnetEscrowdoes not perform any checks on this field. * Manipulate other host'sSubnetSettlementHostStats.Missed* This damage is not currently limited,SettleSubnetEscrowdoes not perform any checks on this field.They cannot: * Increase their
RewardCoinsfor the epoch: these are tied to the host's weight.There are two ways a dishonest actor can land in a
devshardsvulnerable to hijacking: * By pure chance. This chance is higher when the host has higher weight / thedevshardsis smaller in size. * By "grindingdevshards". The actor acts as both Host and User, and repeatedly creates/settlesdevshards, without performing any inferences, until they land in a vulnerabledevshards. * Note that, in this scenario, the actor cannot profit from the attack by manipulatingSubnetSettlementHostStats.Cost, since they'd only be transferring tokens from their User account to their Host account.Solution
In order for
devshards's stats to be safely aggregated with epoch-level stats, we need to: * When a host lands on a vulnerabledevshardby chance, limit the damage they can do to other hosts'Missed/Invalidatedinference count. * Prevent dishonest actors from grindingdevshardsto augment damage done to other hosts.Limit
Missed/InvalidatedThese counters should be capped to their proportional share of the amount of inferences.
E.g. if, given the amount of tokens put into escrow, we infer that at most 500 inferences can be run, then a Host's
Missed+Invalidatedcannot be greater than (500 inferences / 128 slots * host's slot count).If we cannot infer how many inferences can be run from a given escrow amount, then: * The user can specify in
MsgCreateSubnetEscrowhow many inferences they plan on running. They can request inferences until either the escrow amount is depleted or the inference limit is reached, whichever happens first.devshardsfeeHaving a fee on creation/settlement of
devshardswould discourage dishonest actors from grindingdevshardsto damage other hosts.Notes: * The fee must be paid even if there are no inference requests, to prevent actors from repeatedly creating+closing
devshards. * The fee should not scale with the number of requests performed (to encourage users to createdevshardswith bigger escrow amounts instead of a lot of smaller ones)A simple approach could be to pay
Ntokens per Host in the network, paid upon settlement.Question: how should we quantify this fee? In general, fees need to be greater than the theoretical profit in order to discourage a given behaviour. However, this attack is not profit-driven.