feat: dispute and resolve-dispute handling (ADR-013 slice 5) - #86
Merged
Conversation
Last slice of ADR-013/#78: pallet-network-validator's dispute_round and resolve_dispute, split across two binaries by necessity, not choice -- dispute_round is directly signed by the disputing validator's own account, but resolve_dispute is SuspensionOrigin-gated (EnsureRoot in this runtime), so only the Control Plane's own bridge/sudo account can call it. internal/blockchainbridge/networkvalidatorregistrar.go: - Registrar.DisputeRound (call_index 7): directly signed, fixed-width encoding matching submit_evidence/close_round's established shape. Deliberately a manual CLI action, never triggered by the challenge loop itself -- ADR-013 §9's own reasoning: a validator disputing algorithmically on every disagreement would just move the trust problem, not solve it. - Registrar.SubmitSudo + Registrar.ResolveDispute (call_index 8): SubmitSudo is SubmitDirect's sibling for SuspensionOrigin/EnsureRoot -gated calls, mirroring the exact sudo-wrapping EnsureActive/ EnsureLeaseActive already use inline, just factored out. uphold encodes as a single SCALE bool byte (0/1). - ParseScoreDimension (String's inverse) for the two new CLI subcommands' dimension argument. cmd/networkvalidator: new `dispute <provider-hex> <round> <dimension>` subcommand, directly signed by the validator's own key like register/status/request-exit/withdraw/run. cmd/controlplane-admin: new `resolve-dispute <provider-hex> <round> <dimension> <uphold|reject>` subcommand -- restructured run() to dispatch on the subcommand before connecting to any credential store, since this is the first subcommand that needs chain access instead of Postgres (user/API-key commands never touch the chain; resolve-dispute never touches Postgres). Known, explicitly out-of-scope gap (documented in ADR-013's implementation note and in DisputeRound's doc comment): the pallet's dispute_round also authorizes the scored provider to dispute, not only a committee validator -- that path is real on-chain but not reachable by any tool in this MVP, since a provider has no independent chain-signing path (AGENTS.md: the Provider Agent never talks to the chain directly). A future Control-Plane-proxied dispute_round_for, mirroring register_provider_for's already-accepted delegation pattern, is the natural way to close that gap. Tests: encodeDisputeRoundCall/encodeResolveDisputeCall byte-layout tests matching the established encodeSubmitEvidenceCall/ encodeCloseRoundCall pattern, including an explicit check that uphold/reject differ by exactly one trailing byte. Verified (control-plane/): gofmt -l .; go build ./...; go vet ./...; go test ./... -count=1 -- full workspace green. Both new CLI paths smoke-tested against the live local dev chain: argument validation rejects malformed input correctly, and a well-formed call reaches the RPC submission layer and fails with the same already-documented "unreachable" wasm trap as every other pallet-network-validator extrinsic in this sandbox (the deployed chain's wasm predates this pallet -- see PR #79's description for the original finding via state_getMetadata; not a new issue, not a regression). Closes #78 (all five ADR-013 slices now implemented). #29 remains open only for whatever broader scope beyond the daemon itself it still represents -- worth a fresh look now that the daemon is complete. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Last slice of ADR-013/#78: pallet-network-validator's
dispute_roundandresolve_dispute, split across two binaries by necessity, not choice —dispute_roundis directly signed by the disputing validator's own account, butresolve_disputeisSuspensionOrigin-gated (EnsureRootin this runtime), so only the Control Plane's own bridge/sudo account can call it.Closes #78 — all five ADR-013 slices are now implemented.
internal/blockchainbridge/networkvalidatorregistrar.goRegistrar.DisputeRound(call_index 7): directly signed, fixed-width encoding matchingsubmit_evidence/close_round's established shape. Deliberately a manual CLI action, never triggered by the challenge loop itself.Registrar.SubmitSudo+Registrar.ResolveDispute(call_index 8):SubmitSudoisSubmitDirect's sibling forSuspensionOrigin/EnsureRoot-gated calls, mirroring the exact sudo-wrappingEnsureActive/EnsureLeaseActivealready use inline.ParseScoreDimension(String's inverse) for the two new CLI subcommands.cmd/networkvalidatorNew
dispute <provider-hex> <round> <dimension>subcommand, directly signed like the rest of this binary's calls.cmd/controlplane-adminNew
resolve-dispute <provider-hex> <round> <dimension> <uphold|reject>subcommand — restructuredrun()to dispatch on the subcommand before connecting to any credential store, since this is the first subcommand needing chain access instead of Postgres.Known, explicitly out-of-scope gap
The pallet's
dispute_roundalso authorizes the scored provider to dispute, not only a committee validator — real on-chain but unreachable by any tool in this MVP, since a provider has no independent chain-signing path (AGENTS.md: the Provider Agent never talks to the chain directly). A future Control-Plane-proxieddispute_round_for, mirroringregister_provider_for's already-accepted delegation pattern, is the natural fix — not attempted here.Tests
encodeDisputeRoundCall/encodeResolveDisputeCallbyte-layout tests matching the established pattern, including an explicit check that uphold/reject differ by exactly one trailing byte.Verified
gofmt -l .;go build ./...;go vet ./...;go test ./... -count=1— full workspace green. Both new CLI paths smoke-tested against the live local dev chain: argument validation rejects malformed input correctly, and a well-formed call reaches the RPC submission layer and fails with the same already-documented "unreachable" wasm trap as every other pallet-network-validator extrinsic in this sandbox (the deployed chain's wasm predates this pallet — not a new issue).#29
Stays open — its full acceptance criteria include dashboard validator views (challenge outcomes, score history), tracked in #76, plus two gaps ADR-011 itself already flagged as deferred (prohibited-related-worker detection beyond self-scoring, and slashing economics). Will comment on #29 with the precise remaining breakdown.
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com