Commit 45a343a
feat(action,staking,state): commissionRate schema + SetCommissionRate (IIP-59 PR 1/6)
First PR of the IIP-59 protocol-native voter reward distribution
series (spec: iotexproject/iips#73).
Introduces the on-chain delegate opt-in surface — a commissionRate
field on the candidate schema plus the SetCommissionRate action
delegates use to change it. No reward-distribution logic yet: that
lands in PR 3, gated on the same feature flag as this PR. Chain
behavior is unchanged pre-flag.
Schema
------
- stakingpb.Candidate gains commissionRate=11; Go Candidate struct
mirrors it. Equal / Clone / toProto / fromProto updated (the PoC
at iotexproject#4811 missed Equal — flagged in review #2 there).
- state.Candidate gains CommissionRate. Populated per epoch from
staking.Candidate by PutPollResult in PR 2; the latest user-set
value lives on staking.Candidate, and state.Candidate holds the
frozen per-epoch value consumed by GrantEpochReward in PR 3.
- iotextypes.Candidate.commissionRate is set/read in candidateToPb /
pbToCandidate so the field travels through poll snapshots and RPC.
Feature flag
------------
- FeatureCtx.NoVoterRewardDistribution, bound to
!g.IsToBeEnabled(height) per AGENTS.md convention for WIP features
(the gate will be swapped for a real hardfork height at release).
- Named so the bool zero value (false) corresponds to the post-fork
activated behavior, matching NoCandidateExitQueue /
NotSlashUnproductiveDelegates.
Action (SetCommissionRate)
--------------------------
- action/set_commission_rate.go: SetCommissionRate{rate uint64} with
IntrinsicGas (10000) and SanityCheck (rate in [0, 10000]).
- Full Proto / LoadProto / FillAction wiring for the iotex-proto
oneof slot (setCommissionRate = 56) shipped in iotex-proto v0.6.7
(iotexproject/iotex-proto#174).
- EthCompatibleAction + NewSetCommissionRateFromABIBinary so
MetaMask / hardhat can submit via the same path as
candidateActivate / candidateDeactivate.
- PackCommissionRateSetEvent helper producing keccak-anchored topic-0
+ indexed candidate address for the receipt log indexers subscribe
to.
- action/native_staking_contract_interface.sol +
native_staking_contract_abi.json: declare
\`function setCommissionRate(uint64 rate)\` and
\`event CommissionRateSet(address indexed candidate, uint64 newRate)\`
so external tooling has an ABI to bind against.
Handler (staking)
-----------------
- action/protocol/staking/handler_set_commission_rate.go: resolves
the caller to a registered candidate by owner, writes
candidate.CommissionRate, emits CommissionRateSet on the receipt.
No cooldown enforcement — voters already get a ~1.5 epoch reaction
window from the PutPollResult snapshot (§3.4 of the IIP), so a
separate per-rate-change gate is not required.
- validations.go: rejects SetCommissionRate at Validate when the
feature flag is off, so pre-flag the action never leaves mempool.
- protocol.go: registers the action in the handler switch.
Tests
-----
- candidate_test.go / state/candidate_test.go: proto roundtrip +
Equal / Clone coverage for the new field.
- set_commission_rate_test.go: SanityCheck bounds, IntrinsicGas, ABI
encode/decode roundtrip.
- handler_set_commission_rate_test.go: owner check, rate cap,
successful write path, pre-flag Validate rejection, receipt event
encoding.
go.mod
------
- Bumps github.com/iotexproject/iotex-proto to v0.6.7 for the new
SetCommissionRate action + Candidate.commissionRate fields.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent 89e7507 commit 45a343a
18 files changed
Lines changed: 811 additions & 69 deletions
File tree
- action
- protocol
- staking
- stakingpb
- state
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
453 | 453 | | |
454 | 454 | | |
455 | 455 | | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
456 | 462 | | |
457 | 463 | | |
458 | 464 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
34 | 53 | | |
35 | 54 | | |
36 | 55 | | |
| |||
212 | 231 | | |
213 | 232 | | |
214 | 233 | | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
215 | 247 | | |
216 | 248 | | |
217 | 249 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
44 | 51 | | |
45 | 52 | | |
46 | 53 | | |
| |||
82 | 89 | | |
83 | 90 | | |
84 | 91 | | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
85 | 97 | | |
86 | 98 | | |
87 | 99 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
172 | 172 | | |
173 | 173 | | |
174 | 174 | | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
175 | 189 | | |
176 | 190 | | |
177 | 191 | | |
| |||
346 | 360 | | |
347 | 361 | | |
348 | 362 | | |
| 363 | + | |
349 | 364 | | |
350 | 365 | | |
351 | 366 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
38 | 42 | | |
39 | 43 | | |
40 | 44 | | |
| |||
65 | 69 | | |
66 | 70 | | |
67 | 71 | | |
| 72 | + | |
68 | 73 | | |
69 | 74 | | |
70 | 75 | | |
| |||
79 | 84 | | |
80 | 85 | | |
81 | 86 | | |
82 | | - | |
| 87 | + | |
| 88 | + | |
83 | 89 | | |
84 | 90 | | |
85 | 91 | | |
| |||
274 | 280 | | |
275 | 281 | | |
276 | 282 | | |
| 283 | + | |
277 | 284 | | |
278 | 285 | | |
279 | 286 | | |
| |||
324 | 331 | | |
325 | 332 | | |
326 | 333 | | |
| 334 | + | |
327 | 335 | | |
328 | 336 | | |
329 | 337 | | |
| |||
341 | 349 | | |
342 | 350 | | |
343 | 351 | | |
| 352 | + | |
344 | 353 | | |
345 | 354 | | |
346 | 355 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
180 | 180 | | |
181 | 181 | | |
182 | 182 | | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
183 | 225 | | |
184 | 226 | | |
185 | 227 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
0 commit comments