Skip to content

v0.9.0

Latest

Choose a tag to compare

@envestcc envestcc released this 29 Sep 03:32
dcaa777

Zanzibar (IIP-59) support: the two new staking actions, and the BLS public key plus proof of possession on candidate register/update.

New

SetVoterRewardOptInMethod / SetVoterRewardOptInRequest — opts a delegate into protocol-native voter reward distribution (ActionCore field 57). No payload; the sender is the delegate. It is one-way — the protocol has no counterpart action to opt back out.

Opting in with no reward portions published on the DelegateProfile contract is silently harmful rather than rejected: the protocol cannot tell "unset" from "explicit zero", falls back to 100% commission, and pays every voter zero while producing successful distributions.

SetVoterRewardDestinationMethod / SetVoterRewardDestinationRequest — redirects the sender's own voter rewards (field 58). Passing your own address clears the override.

blsPubKey / blsPop on CandidateRegisterRequest and CandidateUpdateRequest — hex, with or without a 0x prefix. Optional: leave them null to register or update without a key, and to leave an already registered key untouched. The proof must be over the candidate's owner address; Zanzibar rejects it otherwise with ErrUnauthorizedOperator (203) on the receipt.

Three behaviours worth knowing:

  • A 0x prefix is stripped. Numeric.hexStringToByteArray does not do it — it reads '0' and 'x' as a byte, and Character.digit('x', 16) is -1 — so a prefixed key would decode to something corrupt of a plausible length, sign cleanly, and be rejected on chain with no indication why. Every tool that emits a BLS key quotes it with the prefix.
  • Absent stays absent. A null or empty field is left unset rather than set to empty bytes, so an update that does not mention a key leaves an already registered one alone.
  • A proof with no key throws. That pairing is invalid in every fork era and the chain rejects it at validation, before a receipt exists, so the caller would otherwise get a bare RPC error with no action hash to look up.

Proto

action.proto picks up SetVoterRewardOptIn (57), SetVoterRewardDestination (58), CandidateDeactivate (54), ScheduleCandidateDeactivation (55), and blsPubKey / blsPop on CandidateBasicInfo. Every message and field number was checked against iotex-proto v0.6.13. Field 56 (SetCommissionRate) is deliberately omitted: no iotex-core release implements it, and a node answers no applicable action to handle proto type.

Envelop detects the opt-in by presence rather than payload length — it serializes to zero bytes, so a length check drops it silently and turns a delegate's one-way action into a no-op.

Also since v0.8.1: CI bumped to actions/checkout@v5 / setup-java@v5, and bcprov-jdk15to18 1.71 → 1.74.

Verification

Against a local four-delegate chain running iotex-core v2.5.0 with Zanzibar, Beta and Gamma active:

  • both IIP-59 actions accepted on chain
  • BLS: a proof bound to the candidate settles status 1; one bound to a different candidate settles 203. The pair is what separates "the chain accepted this" from "the chain verified this"
  • voter reward payout transaction logs decode correctly. IIP-59 adds no new TransactionLogType — payouts reuse CLAIM_FROM_REWARDING_FUND — but the sender is the protocol pool pseudo-address io0000000000000000000000rewardingprotocol, which has no 20-byte hash behind it and comes back empty from anything that decodes an address the ordinary way

Live tests skip unless IOTEX_TEST_KEY is set. IOTEX_TEST_ENDPOINT / IOTEX_TEST_CHAINID / IOTEX_TEST_SECURE aim them at a local chain; the defaults still point at TestNet.