Skip to content

feat(sidecar): gov-param-change task (PLT-487)#203

Merged
bdchatham merged 2 commits into
mainfrom
plt-487-gov-param-change
Jun 13, 2026
Merged

feat(sidecar): gov-param-change task (PLT-487)#203
bdchatham merged 2 commits into
mainfrom
plt-487-gov-param-change

Conversation

@bdchatham

Copy link
Copy Markdown
Contributor

Adds a gov-param-change sidecar task — submits a v1beta1 ParameterChangeProposal signed by the operator account, mirroring gov-software-upgrade.

The load-bearing decision: the per-change value is carried as json.RawMessage and string()-converted exactly once in buildParamChangeMsg. So any JSON shape — scalar 100, string "86400000000000", bool, or object — reaches the chain single-encoded. This structurally prevents the double-encode-at-apply bug that consumed the deposit on the arctic-1 prop-252 first draft.

  • usei-denom deposit guard (mirrors gov-software-upgrade)
  • param-change-specific REHYDRATION WARNING — unlike software-upgrade, a param-change has no apply-once safety net, so a rehydration double-submit is two real proposals + two deposits
  • isExpedited deferred (honored only via NewMsgSubmitProposalWithExpedite, not the content field)
  • Test covers the single-encode regression (object + scalar + string + bool), non-usei deposit rejection, empty-changes rejection

Wires engine.TaskGovParamChange, client.GovParamChangeTask, and the serve.go registry. go build/go vet/tests green.

Design (Coral-signed-off, Brandon-approved): bdchatham-designs designs/wave/seinode-govparamchange-submit-proposal.md. First half of PLT-487 (seictl → release → controller bump).

🤖 Generated with Claude Code

Adds a gov-param-change sidecar task that submits a v1beta1
ParameterChangeProposal signed by the operator account, mirroring
gov-software-upgrade. The per-change value is carried as json.RawMessage
and stringified exactly once in buildParamChangeMsg — so any JSON shape
(scalar/string/bool/object) reaches the chain single-encoded, structurally
preventing the double-encode-at-apply bug. usei-denom deposit guard;
param-change-specific REHYDRATION WARNING (no apply-once safety net).
isExpedited deferred (honored only via NewMsgSubmitProposalWithExpedite).

Wires engine.TaskGovParamChange, client.GovParamChangeTask, and the serve.go
handler registry. Test covers the single-encode regression for object + scalar
values, non-usei deposit rejection, and empty-changes rejection.

Design: bdchatham-designs designs/wave/seinode-govparamchange-submit-proposal.md (PLT-487).
@cursor

cursor Bot commented Jun 13, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Submits real governance proposals and spends deposits via the operator keyring; rehydration can double-submit proposals (documented, not fixed in this PR). Changes are localized to a new task handler and codec registration.

Overview
Adds a gov-param-change sidecar task so operators can submit v1beta1 ParameterChangeProposal txs through the same sign-and-broadcast path as gov-software-upgrade.

The task is wired end-to-end: engine.TaskGovParamChange, client.GovParamChangeTask (validation + wire params), serve.go handler registration, and a new GovParamChanger handler that builds MsgSubmitProposal and calls SignAndBroadcast. Per-change value is carried as json.RawMessage and converted with a single string() in buildParamChangeMsg so param JSON is not double-encoded at apply time; client docs call out large integers as JSON strings to avoid float64 precision loss on decode.

transactions.go registers x/params proposal interfaces on the sign-tx registry so ParameterChangeProposal encodes correctly without pulling wasm deps. Deposit validation mirrors the upgrade task (usei only). Docs stress rehydration risk: unlike software upgrades, duplicate submits create multiple live proposals and deposits until #174’s idempotency marker exists.

Reviewed by Cursor Bugbot for commit 3b5a00a. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a9dbc9d. Configure here.

Comment thread sidecar/tasks/gov_param_change.go
…cs/tests (review)

- CRITICAL: newSignTxInterfaceRegistry now registers the x/params proposal
  package — without it, packing a ParameterChangeProposal into an Any fails at
  TxEncoder at runtime. CGO_ENABLED=0 build verified clean (proposal doesn't
  pull x/wasm).
- Add TestGovParamChangeHandler_HappyPath (threads signAndBroadcast end-to-end;
  proves the registration) + a Terminal-error validation table.
- Document that integer-valued params must be JSON strings, not bare numbers
  (the sidecar map decode is float64-based; >2^53 loses precision). Sei
  large-integer params are string-encoded by convention. UseNumber() on the
  shared server decode is a tracked follow-up.
@bdchatham bdchatham merged commit 8dce789 into main Jun 13, 2026
3 checks passed
@bdchatham bdchatham deleted the plt-487-gov-param-change branch June 13, 2026 15:26
bdchatham added a commit that referenced this pull request Jun 13, 2026
…204)

Follow-up to #203. The `gov-param-change` handler was tested, but the
client `GovParamChangeTask` builder had no coverage (flagged in
cross-review). Adds:

- **`Validate()` table** — valid + every failure branch.
- **`ToTaskRequest()`** — type + required param keys +
memo-omitted-when-empty.
- **`ValueSingleEncodedOnWire`** — the client-side half of the
single-encode contract: the per-change value survives `ToTaskRequest` +
the HTTP `json.Marshal` **byte-identical** for
object/string/number/bool, complementing the handler-side regression
guard. This is the full client→wire path the prior unit test bypassed.

Test-only; no behavior change.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

1 participant