feat!: add subnet add-validator + align P-Chain command names with avalanchego tx types (v2.0.0)#33
feat!: add subnet add-validator + align P-Chain command names with avalanchego tx types (v2.0.0)#33owenwahlgren wants to merge 4 commits into
subnet add-validator + align P-Chain command names with avalanchego tx types (v2.0.0)#33Conversation
Adds a validator to a permissioned subnet via AddSubnetValidatorTx, the classic path for managing validators on a permissioned subnet (distinct from `l1 register-validator`, which targets converted L1s). - pkg/pchain: AddSubnetValidator + issuer seam/config, mirroring the existing interface-based issue*Tx helpers - cmd/subnet: `subnet add-validator` with --subnet-id/--node-id/--weight /--start/--duration; subnet owner authorizes via subnet auth, so the wallet is loaded tracking the subnet - tests: pchain unit test + e2e help/missing-args coverage - docs: usage.md and pchain-operations.md
Rename commands so each maps 1:1 to the avalanchego transaction it issues, keeping the previous names as deprecated aliases (a warning is printed when an alias is used). pchain function names already matched the tx types. Renames (old name kept as alias): - validator add -> validator add-permissionless - validator delegate -> validator add-permissionless-delegator - subnet convert-l1 -> subnet convert-to-l1 - l1 set-weight -> l1 set-validator-weight - l1 add-balance -> l1 increase-validator-balance Also annotates each command's Short help with its tx type, adds a shared warnIfDeprecatedAlias helper, an e2e alias-deprecation test, and updates docs (usage.md, pchain-operations.md) and CLAUDE.md.
subnet add-validator command (AddSubnetValidatorTx)subnet add-validator + align P-Chain command names with avalanchego tx types
BREAKING CHANGE: the previous command names are removed entirely (no aliases). Old names now error with "unknown command". Migrate: - validator add -> validator add-permissionless - validator delegate -> validator add-permissionless-delegator - subnet convert-l1 -> subnet convert-to-l1 - l1 set-weight -> l1 set-validator-weight - l1 add-balance -> l1 increase-validator-balance - drop Aliases + warnIfDeprecatedAlias helper - command groups (validator/subnet/l1) now reject unknown subcommands via requireSubcommand so removed names fail loudly (exit 1) - e2e: assert old names are rejected; docs reframed as v2.0.0 migration
|
@federiconardelli7 heads-up — this PR changed materially since your approval, so it needs another look before merge. What changed: we turned the command rename into a hard cutover (breaking). The deprecated aliases are gone — the old names ( Impact: this is now a v2.0.0 / breaking release rather than the backward-compatible v1.1.0 you approved. New commits since your review:
CI is green (build, vet, staticcheck, unit, offline e2e). Companion docs PR: ava-labs/builders-hub#4304. Mind taking another pass? 🙏 |
There was a problem hiding this comment.
Reviewed the full PR — all changed files plus cmd/chain.go, go.mod, and the CI workflows. The new subnet add-validator and the rename are well done: the rename is applied consistently (I swept the repo for leftover old names and found none), pkg/pchain follows the existing issuer-seam pattern with a thorough unit test, and requireSubcommand correctly turns a removed name into exit 1 + unknown command (verified against root.go's SilenceErrors/SilenceUsage and Execute()).
Things to look at — left inline, summarized here:
1. (should-fix) The removed-names guard does not run in CI. ci.yml runs go test -tags=clie2e ... -run 'Help|Params|MissingArgs', which TestCLIRemovedOldNamesRejected does not match — so it is compiled (staticcheck) but never executed. Extending that -run filter (e.g. ...|RemovedOldNames) would make the guard real. (Inline on the test.)
2. (minor) chain was left out of the conventions applied everywhere else. chain create's Short is still 'Create a new chain' — the only canonical command with no (CreateChainTx) annotation — and chainCmd did not get requireSubcommand, so platform chain <typo> still silently prints help and exits 0, the footgun requireSubcommand fixes for the other groups. transfer/keys/wallet/node are in the same boat. Out of scope for the rename, but worth a follow-up. (cmd/chain.go is unchanged, so no inline comment.)
3. (minor) Small items on the new command's validation and its test — inline on cmd/subnet.go and e2e/cli_test.go.
Process note: since old names are removed outright, make sure the release is cut as a major version bump.
Net: implementation looks solid; the main actionable item is wiring the removed-names guard into CI so the cutover stays protected.
| return fmt.Errorf("invalid node ID: %w", err) | ||
| } | ||
|
|
||
| start, end, err := parseTimeRange(subnetValStartTime, subnetValDuration) |
There was a problem hiding this comment.
Question on --start: avalanchego is pinned at v1.14.1 (post-Durango), where I believe the P-chain ignores the tx Start for subnet/permissionless validators — they begin at acceptance. If that is right, parseTimeRange returning now+30s and feeding it into the tx has no on-chain effect, so --start is effectively a no-op and might deserve a note in the flag help. Not specific to this PR (the existing add-permissionless commands do the same) — just flagging it since this new flag advertises a start time.
| if err != nil { | ||
| return err | ||
| } | ||
| if !end.After(start) { |
There was a problem hiding this comment.
Lighter validation than the sibling add-permissionless / add-permissionless-delegator, which also check end.Sub(start) >= netConfig.MinStakeDuration and return a friendly local error. Here only end > start is enforced, so a too-short or out-of-window period only fails at the network. Optional, but a local duration check would give a clearer message.
|
|
||
| // TestCLIRemovedOldNamesRejected verifies the v2.0.0 hard cutover: the old | ||
| // command names were removed (no aliases) and are now rejected as unknown. | ||
| func TestCLIRemovedOldNamesRejected(t *testing.T) { |
There was a problem hiding this comment.
Good guard for the cutover. One catch though: CI's smoke step runs go test -tags=clie2e ... -run 'Help|Params|MissingArgs' (.github/workflows/ci.yml), and this test name matches none of those patterns, so it is compiled via staticcheck but never actually executed in CI. Adding a matching pattern (e.g. ...|RemovedOldNames) to that -run filter would make sure the guard runs. Side note: the test command in the PR description references DeprecatedAlias, which does not exist.
| t.Error("expected error when missing required args") | ||
| } | ||
|
|
||
| if !strings.Contains(stderr, "subnet-id") { |
There was a problem hiding this comment.
Minor: because this subnet-id check uses t.Logf, the test only really asserts err != nil — a wrong or empty error message would not fail it. t.Errorf would make it a real assertion. This matches the existing convention in the other ...MissingArgs tests in this file, so feel free to treat it as optional (or a small file-wide cleanup).
…r polish Addresses @federiconardelli7's re-review of #33: - ci.yml: add RemovedOldNames + UnknownSubcommand to the clie2e -run filter so the cutover guards actually execute in CI (were compiled-only before) - apply requireSubcommand to root + chain/transfer/keys/wallet/node so an unknown subcommand errors (exit 1) instead of silently printing help; annotate `chain create` Short with (CreateChainTx) - subnet add-validator: add local min-duration check mirroring add-permissionless (friendly error instead of network-only failure) - note on --start that post-Durango networks ignore it (validator starts at acceptance) on subnet add-validator + the two validator commands; verified against avalanchego v1.14.1 staker_tx_verification.go - e2e: real t.Errorf assertion in TestCLISubnetAddValidatorMissingArgs; new TestCLIUnknownSubcommandRejected covering the newly-guarded groups
subnet add-validator + align P-Chain command names with avalanchego tx typessubnet add-validator + align P-Chain command names with avalanchego tx types (v2.0.0)
|
Thanks for the thorough re-review @federiconardelli7 — all addressed in 1. (should-fix) Removed-names guard not running in CI ✅ — extended the 2. (minor) Footgun + 3a. (minor) 3b. (minor) Lighter validation than siblings ✅ — 4. (minor) Process note (major bump) ✅ — will cut as v2.0.0; PR title/description updated to reflect the breaking hard cutover (and fixed the stale I scoped the broader |
What
Two related changes, shipping as a breaking v2.0.0 release:
1. New command:
subnet add-validatorAdds a validator to a permissioned subnet via
AddSubnetValidatorTx— the gap where the CLI could add primary-network validators and L1 validators but not permissioned-subnet validators.--weightis sampling weight, not a stake amount.2. Align command names with avalanchego tx types (BREAKING)
Every P-Chain command now maps 1:1 to the avalanchego transaction it issues. Old names are removed (no aliases) and now error with
unknown command(exit 1):validator addvalidator add-permissionlessvalidator delegatevalidator add-permissionless-delegatorsubnet convert-l1subnet convert-to-l1l1 set-weightl1 set-validator-weightl1 add-balancel1 increase-validator-balanceCommand groups (root + validator/subnet/l1/chain/transfer/keys/wallet/node) now reject unknown subcommands via
requireSubcommandinstead of silently printing help + exiting 0.Changes
pkg/pchain:AddSubnetValidator+AddSubnetValidatorConfig+addSubnetValidatorTxIssuerseam (matches the existing interface-basedissue*Txpattern).cmd/: command renames;requireSubcommandguard; tx-type annotations inShorthelp;--startno-op note (post-Durango).TestIssueAddSubnetValidatorTx(unit); e2eTestCLIRemovedOldNamesRejected,TestCLIUnknownSubcommandRejected,TestCLISubnetAddValidatorMissingArgs.docs/usage.md,docs/pchain-operations.md(migration table). Companion builders-hub docs PR: docs(platform-cli): align with v2.0.0 command renames + add subnet add-validator builders-hub#4304.Backward compatibility
Breaking. Old command names are removed and must be migrated (see table). Cut as a major version bump (v2.0.0).
Testing
go build,go vet ./...,staticcheck ./...,gofmt— cleango test ./pkg/...— passgo test -tags=clie2e ./e2e/... -run "Help|Params|MissingArgs|RemovedOldNames|UnknownSubcommand"— pass (matches the CI smoke filter)